1 环境安装
首先需要安装 OpenCV 及 CUDA 环境安装,有 TX2 平台下 OpenCV 和 CUDA 参考百度.注意 TX2 自带了 OpenCV2.14,如果需要安装高版本的 OpenCV 话需要注意多版本管理的问题.安装完成后,可以编译 OpenCV 例程来判断 OpenCV 是否安转完成,CUDA 安装可以在终端输入
nvcc
如果终端打印下面信息,表示安装完成
2 CUDA 编译流程
CUDA 的程序通过 nvcc 编译器编译成可执行文件,CUDA 的可执行文件有两种,分别是在 Host 上执行的 CPU 相关代码,另一部分是在 Device 上执行的 GPU 代码,nvcc 编译的指令与 gcc/g++ 编译器差不多,基本指令如下
nvcc --gpu-architecture=compute_62 --gpu-code=compute_62 -I/usr/local/cuda/include/ -c kernels.cu -o kernels.o
其中:
--gpu-architecture 和 --gpu-code 指定了 GPU 的计算能力,请根据自己 GPU 的运算能力修改,有关 GPU 运算能力可以在 这里 查找(NVIDIA 官网挂了,将就着在维基百科里面看吧),--gpu-architecture 指定 ptx 将来可以生成怎么样的版本,--gpu-code 指定马上生成的代码版本,--gpu-architecture 和 --gpu-code 可以有多个值,这样 nvcc 会将多个版本的代码一同放在 fatbin 文件中,
-I/usr/local/cuda/include / 指定了 CUDA 包含头文件的目录,如果还有其他的头文件,要将这些头文件的路径包含进来(见 3)
-c 表示只对源文件进行编译,不进行链接,及将. cu 文件编译生成. cu 文件
-o 指定要生成. o 文件的文件名
还有其他的一些编译选项可以参考 NVIDIA 的 nvcc 编译手册,在 CUDA 的安装目录下可以找到
3 CUDA 与 OpenCV 混合编译
CUDA 与 OpenCV 的混合编译其实就是讲. cu 文件与. c/.cpp 文件混合编译,编译的方法比较多,NVIDIA 官网有介绍利用 cmake 进行编译的方法,点 这里 ,网上介绍的比较多的也是利用 cmake 进行编译,使用 Makefile 编译的教程比较少,这里介绍一下利用 Makefile 对 CUDA 与 c++ 进行混合编译.
其实 CUDA 与 c/c++ 一起编译原理很简单,CUDA C 也只是一个拓展的 c 语言集,所以我采用的是利用 nvcc 编译器和 g++ 分别对. cu 文件和. cpp 文件进行编译,生成. o 文件,然后利用 g++ 进行链接,实测方法可行.因为我 CUDA 的程序全部都在. cu 文件中,然后在. cpp 文件中通过 extern 对 CUDA 的函数申明,像下面这样:
/*main.cpp*/
extern int buildMaps(float *model, float *input, float *output, int height, int width);
int main()
{
/*初始化代码*/
......
buildMaps((float *)model, (float *)input, output, width, width);
/*other*/
......
}
/*kernel.cu*/
/*GPU内核函数*/
__global__ void kernel_compute(float *model, float *input, float *output)
{
......
}
int buildMaps(float *model, float *input, float *output, int height, int width)
{
/*init*/
......
kernel_compute <<<grid, block>>> (dev_m, dev_i, dev_o);
/*other*/
......
}
所以这里的 OpenCV 代码像普通 OpenCV 代码一样写 Makefile 就行,写 CUDA 的代码的 Makefile 时注意,如果. cu 文件中有 OpenCV 的相关代码的话, 需要在 nvcc 编译的时候添加
-DOPENCV `pkg-config --cflags opencv-3.4`
用来指定 OpenCV 的包含头文件路径,没有错误的话,编译完成就可以使用 g++ 链接就可以了.
这里贴一下我自己在用的一个 Makefile 模板,写的比较粗糙,不过平常的编译基本够了,中小型的工程的 Makefile 都可以用这个模板修改的到,模板有不完善的地方还请大家指正
#cpp源文件路径
SRCS = $(wildcard ./src/*.cpp)
#cu文件路径
CU_SRC = $(wildcard ./src/*.cu)
#.o文件
OBJS = $(patsubst %.cpp,%.o,$(SRCS))
CU_OBJ = $(patsubst %.cu,%.o,$(CU_SRC))
#g++和nvcc编译器
CXX = g++
NVCC = nvcc
#C/C++编译选项 -- OpenCV头文件路径
CFLAGS = `pkg-config --cflags opencv-3.4`
#C/C++编译选项 -- 当前工程头文件路径及优化选项(-O3)
CFLAGS += -I./include/ -std=c++11 -O3
#开启OpenMP
CFLAGS += -fopenmp
#CUDA C编译选项
NVFLAGS = --gpu-architecture=compute_62 --gpu-code=compute_62
NVFLAGS += -DOPENCV `pkg-config --cflags opencv-3.4`
#C/C++链接器选项 -- OpenCV库及其路径
LDFLAGS = `pkg-config --libs opencv-3.4` -O3
LDFLAGS += -fopenmp
#C/C++链接器选项 -- CUDA8.0库及其路径
NVLDFLAGS = `pkg-config --libs cuda-8.0`
#最终目标
EXE = video
#OpenMP选项 -- 指定绑定CPU
GOMP_CPU_AFFINITY="0 3 4 5"
#链接
$(EXE) : $(OBJS) $(CU_OBJ)
@echo Linking ...
@$(CXX) -o $@ $^ $(LDFLAGS) $(NVLDFLAGS)
#C/C++编译
%.o : %.cpp
@echo Compiling {$1}lt; ...
@$(CXX) $(CFLAGS) -c #C/C++编译选项 -- OpenCV头文件路径lt;
@-mv *.o src/
#CUDA C编译
%.o : %.cu
@echo NVCC Compiling {$1}lt; ...
@$(NVCC) $(NVFLAGS) -c #C/C++编译选项 -- OpenCV头文件路径lt;
@-mv *.o src/
.PHONY:clean
clean :
-rm src/*.o
-rm $(EXE)
来源: http://www.bubuko.com/infodetail-2471397.html