【gcc, cmake, eigen, opencv,ubuntu】二.gcc编译选项

这篇具有很好参考价值的文章主要介绍了【gcc, cmake, eigen, opencv,ubuntu】二.gcc编译选项。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

gcc编译选项

1.-march=native

其中-march选项就是就是指定目标架构的名字,gcc就会生成针对目标架构优化的目标代码,如-march=prescott会生成针对i5或i7的目标码,从而充分发挥cpu的性能。自gcc4.2,引入了-march=native,从而允许编译器自动探测目标架构并生成针对目标架构优化的目标代码,这比手工设置要安全的多。如何知道-march=native启用了哪些优化指令呢?

找一个任意c源代码文件,用gcc编译看一下即知答案。
gcc -Q --help=target -march=native [xxx].c
启用了哪些优化指令一目了然。

CFLAGS=“-O2 -march=native -pipe”

2.-pipe

多核系统用-pipe可以提高编绎速度。
GCC编绎C程序时首先生成汇编文件,再调用汇编器生成目标文件。-pipe可以使这两个过程同时进行。GCC一边输出汇编代码,汇编器一边进行汇编。如果是多核系统,这两个过程由不同的CPU运行,就可以加快速度。如果是单核系统,就起不到提速的效果了,反而会多用内存。

GCC 的-pipe选项用于将编译器的输出直接传递给下一个阶段,而不是将中间文件写入磁盘,这样可以节省磁盘空间,提高编译速度,因为避免了中间文件的磁盘读写操作。
通常情况下,机器如果有足够的内存,建议使用-pipe选项,加快编译速度,减少磁盘读取。但是如果内存不足,会导致系统使用交换空间,降低编译速度,影响系统性能。

总之-pipe提高的是编译速度,如果编译对你来说没那么重要可以不设置。

3.-O2

优化等级

4.-fPIC

fPIC的全称是 Position Independent Code, 用于生成位置无关代码(看不懂没关系,总之加上这个参数,别的代码在引用这个库的时候才更方便,反之,稍不注意就会有各种乱七八糟的报错)。
使用-fPIC选项生成的动态库,是位置无关的。这样的代码本身就能被放到线性地址空间的任意位置,无需修改就能正确执行。通常的方法是获取指令指针的值,加上一个偏移得到全局变量/函数的地址。

果指定-shared不指定-fPIC会报错

5.-L

-L 添加链接库路径
-L 后跟路径,告诉链接器从哪找库(.so文件),只有在链接时会用到。

如:-L /home/hello/lib

表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找顺序是:/home/hello/lib–>/usr/lib–>/usr/local/lib。

可以加多个包含路径,链接器的寻找顺序为添加的顺序。

6.-l 添加引用链接库

-l 在链接时用到,它的作用是告诉链接器,要用到哪个库。 如:-l pthread

告诉链接器(linker),程序需要链接pthread这个库,这里的pthread是库名不是文件名,具体来说文件句是libpthread.so。

7. -I 添加头文件路径

示例:

g++ -march=native -O3 src.cpp -o out  /opt/mkl/mkl/lib/intel64/libmkl_rt.so -I/opt/mkl/mkl/include -L/opt/mkl/mkl/lib/intel64
 `pkg-config --cflags opencv4 --libs opencv4`

8.-shared和-static

用于生成动态和静态链接库

9. -fopenmp

启用openmp多线程。

10.opencv依赖

`pkg-config --cflags opencv4 --libs opencv4`

11.示例1

g++ -fopenmp -march=native -O3 src.cpp -o out  /opt/mkl/mkl/lib/intel64/libmkl_rt.so -I/opt/mkl/mkl/include -L/opt/mkl/mkl/lib/intel64
 `pkg-config --cflags opencv4 --libs opencv4`
  1. g++ -fopenmp -march=native -O3 src.cpp -o out
  2. /opt/mkl/mkl/lib/intel64/libmkl_rt.so
  3. -I/opt/mkl/mkl/include
  4. -L/opt/mkl/mkl/lib/intel64
    编译, 依赖库, 依赖库的头文件目录,依赖库的库文件目录

12.示例2:实践 eigen编译选项和运行时间示例

利用eigen库实现矩阵相乘,实验不同的编译选项得到的程序的运行时间。用了三种测量运行时间的方法。
为什么用三种方法测时间呢,因为用clock()测多线程程序是不准确的。

源代码如下:eigen.cpp

//#define EIGEN_USE_MKL_ALL //如果适用mkl,取消该行注释
#define EIGEN_VECTORIZE_SSE4_2
#include <iostream>
#include <eigen3/Eigen/Dense>

using Eigen::MatrixXd;
#include <sys/time.h>
#include <ctime>
#include <chrono>
using namespace Eigen;
using namespace std;

int main()

{
	int n;
	n = 1000;

	MatrixXd a = MatrixXd::Random(n,n);
	MatrixXd b = MatrixXd::Random(n,n);
	MatrixXd c;

	struct timeval t1,t2;
	double timeuse;
    gettimeofday(&t1,NULL);

	auto t_start = std::chrono::high_resolution_clock::now();

	clock_t start = clock();

	int N = 10;
	for (int i =0;i < N; i++)
	{
		c = a * b;
	}

	clock_t end = clock();
	double elapsed_time = (double (end) - double(start)) / CLOCKS_PER_SEC / N;

	auto t_end = std::chrono::high_resolution_clock::now();
    double elapsed_time_us = std::chrono::duration<double, std::micro>(t_end-t_start).count();
	cout << "time in micro second " << elapsed_time_us/N <<endl;

	gettimeofday(&t2,NULL);
    timeuse = (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1000000.0;

    printf("timeuse:%lf\n", timeuse / N);
	cout << "Elapsed time is :" << elapsed_time << " (s)" << endl;
	
	return 0;
}

不同的编译命令得到的时间

1.g++ eigen.cpp -o eigen

7.52826 s

2.g++ -march=native eigen.cpp -o eigen

3.65 s

3.g++ -O2 eigen.cpp -o eigen

0.182 s

4.g++ -O2 -march=native eigen.cpp -o eigen

0.05 s

5.g++ -fopenmp -march=native -O2 eigen.cpp -o eigen

3.3 s 什么原因,感觉是挺快的,不像3.3 s
因为是多线程的原因,不应该使用clock()计时,使用下面代码

#include <sys/time.h>
struct timeval t1,t2;
double timeuse;
gettimeofday(&t1,NULL);

func();

gettimeofday(&t2,NULL);
timeuse = (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1000000.0;
printf("timeuse:%lf\n", timeuse);

得到结果 0.042 s

6.python numpy

python numpy同样的矩阵相乘只要
0.012 s

import time
import numpy as np


def main():
  n = 1000
  a = np.random.rand(n, n)
  b = np.random.rand(n, n)

  N = 10
  start = time.time()
  for i in range(N):
    c = np.dot(a, b)
  end = time.time()

  print("Elapsed time is %f (s)" % ((end - start) / N))

if __name__ == '__main__':
    main()
7.方案4和6比较

4和6进行比较
n = 1000时候,0.042和 0.012 s
n = 2000时候,0.39 和 0.029
n = 3000时候,1.27 和 0.06
n = 4000时候,3.08 和 0.12 s, -fopenmp 0.45s 仍然大于 0.12s

python numpy 更快

8.eigen使用mkl , 编译选项

1)mkl安装

我是参考一下第一个链接下载和安装的。
Linux下MKL库的安装部署与使用

cpp, mkl 加速 eigen 实例
Linux 版的 Intel MKL 的安装使用

2)eigen中使用mkl

c++文件开头加入

#define EIGEN_USE_MKL_ALL
#define EIGEN_VECTORIZE_SSE4_2

编译命令变为

g++ -march=native -O2 eigen.cpp -o eigen /opt/mkl/mkl/lib/intel64/libmkl_rt.so -I/opt/mkl/mkl/include -L/opt/mkl/mkl/lib/intel64

eigen use mkl
1000 0.013 s
2000 0.047 s
3000 0.18 s
4000 0.22 s
5000 0.35 s
10000 2.5s

与4和6进行比较 eigen, numpy
n = 1000时候,0.042和 0.012 s
n = 2000时候,0.39 和 0.029
n = 3000时候,1.27 和 0.06
n = 4000时候,3.08 和 0.12 s, -fopenmp 0.45s 仍然大于 0.12s
n = 5000 - 和 0.2
n = 10000 - 和 1.1

eigen use mkl的时间比only eigen少挺多,但仍然是numpy的2倍左右。文章来源地址https://www.toymoban.com/news/detail-489653.html

到了这里,关于【gcc, cmake, eigen, opencv,ubuntu】二.gcc编译选项的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ubuntu 编译安装支持CUDA的OpenCV+其他opencv细节(需要特定版本gcc)

    在安装完“ linux CUDAtoolkit+cudnn+tensorrt 的安装”之后进行支持cuda的opencv安装 否则报错:CMake Error at modules/dnn/CMakeLists.txt:41 (message): DNN: CUDA backend requires CUDA Toolkit. Please resolve dependency or disable OPENCV_DNN_CUDA=OFF - $ nvcc -v ----- Command \\\'nvcc\\\' not found, but can be installed with: sudo apt install nvid

    2024年02月15日
    浏览(54)
  • 查看Eigen、CMake、ceres、opencv版本

    找到eigen本地目录下的Macros.h头文件查看对应的版本。 执行如下命令: sudo gedit /usr/include/eigen3/Eigen/src/Core/util/Macros.h 可以看到Eigen的版本 执行如下命令: cmake --version 即可看到cmake版本 在ceres解压文件夹内找到 package.xml 文件,打开即可查看ceres版本。 输入以下命令: opencv_vers

    2024年02月13日
    浏览(38)
  • arm gcc编译选项

    arm:架构是arm none:不是特定的供应商提供的 eabi:eabi:嵌入式应用二进制接口(Embedded Application Binary Interface) 因为名称里没有“linux”类似的字样,说明不支持操作系统。 libc 是ANSI C 语言函数库,包含了 C 语言最基本的库函数。这个库可以根据头文件划分为 15 个部分,其

    2024年02月03日
    浏览(40)
  • GNU-gcc编译选项-1

    -I  ,比如: -I.   -I ./Platform/include -I ./Platform/include/prototypes -I ./tpm/include -I ./tpm/include/prototypes -I ./Simulator/include -I ./Simulator/include/prototypes   在GCC编译器中,-D是一个编译选项,用于定义预处理器宏。 预处理器宏是一种在编译过程中进行文本替换的机制。通过使用-D选项,可以

    2024年02月11日
    浏览(42)
  • arm-none-eabi-gcc编译、链接选项详解

    \\\"- mthumb ”的意义是:使用这个编译选项生成的目标文件是Thumb指令的,目前还没有发现GNU编译器中有哪一个选项可以指定生成的目标文件是thumb-2的。 相对应的,“-marm“的意义是,使用编译选项生成的目标文件是ARM指令的。 注意,不同编译器对该选项是否默认开启是不一样

    2024年02月11日
    浏览(43)
  • Ubuntu升级Cmake、gcc、g++

    最近要安装llvm,我选择的是从源码安装,所以要使用Cmake进行构建项目。但是服务器上的Cmake、gcc、g++的版本都太低了,不符合要求,所以要对此进行升级。在本博客中采用的升级方法不一定是最好的方法(因为我也是参考其他大佬的博客进行升级的),但是我亲测可行。

    2024年02月11日
    浏览(43)
  • 嵌入式C编译工具:gcc/make/Autotools/cmake

    gcc时GNU编译套件,一种编译器,可以编译c,c++,java等语言。当只有一个文件时,使用gcc编译器就很方便,但是当有多个文件时,编译顺序以及包含关系等使用gcc很麻烦。 make工具:make就相当于一个智能的批处理工具,通过调用makefile实现编译,在makefile规定编译以及链接的顺序

    2024年02月02日
    浏览(53)
  • 【ARM 嵌入式 编译系列 2.5 -- GCC 编译参数学习 --specs=nano.specs选项 】

    请阅读 【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 ARM 工具链 ( arm-none-eabi- ) 包括了一个叫作 --specs 的编译器和链接器选项,这个选项允许用户指定一个或多个 “specs” 文件,以影响编译或链接阶段的行为。Specs 文件包含一系列的命令行参数,这些参数可以是编译器选项

    2024年01月22日
    浏览(50)
  • CMake入门教程【高级篇】编译选项target_compile_options

    target_compile_options 命令允许用户为特定目标(如可执行文件或库)指定编译器选项,这对于优化构建过程和确保代码兼容性至关重要。

    2024年01月15日
    浏览(40)
  • windows下qt creator 配置编译环境gcc,g++,gdb,cmake

    MSVC :即Microsoft Visual C++ Compiler,即微软自己的编译器 MinGW :我们都知道GNU在Linux下面鼎鼎大名的gcc/g++,MinGW则是指Minimalist GNU for Windows的缩写 这里我们选择MinGW,至于Qt中,这两种模式的区别,自行查阅相关资料 在Qt 安装完成之后,gcc.exe,g++.exe,qmake.exe就已经有了,我们可

    2024年02月09日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包