混合編譯.c/.cpp與.cu文件
項目中用到cuda編程,寫了kernel函數,須要nvcc編譯器來編譯。.c/.cpp的文件,假定用gcc編譯。ios
如何混合編譯它們,總體思路是:.cu文件編譯出的東西,做爲最終編譯出的可執行程序的連接依賴。編程
具體提及來又能夠有這幾種狀況:bash
- 分別編譯各個文件,最後連接
- 將CUDA程序編譯爲靜態庫
- 將CUDA程序弄成動態庫
其中後兩種方式更工程化,基於makefile或CMake會更加方便。app
假設手頭上的文件爲:函數
test1.cu test2.c
則具體編譯指令、編譯腳本以下:優化
方法1:分別編譯各個文件
nvcc -c test1.cu gcc -c test2.c gcc -o testc test1.o test2.o -lcudart -L/usr/local/cuda/lib64
方法2: 將cuda程序編譯爲靜態庫
nvcc -lib test1.cu -o libtestcu.a gcc test2.c -ltestcu -L. -lcudart -L/usr/local/cuda/lib64
方法3:將CUDA程序弄成動態庫
以makefile爲例spa
all: c c: libtestcu.so gcc test2.c -ltestcu -L. -lcudart -L/usr/local/cuda/lib64 -o testc libtestcu.so: test.cu nvcc -o libtestcu.so -shared -Xcompiler -fPIC test1.cu
方法4:基於CMake的一個例子
foo.cuh
寫kernel函數聲明 foo.cu
實現kernel函數 foo.cuh
和foo.cu
一塊兒,編譯成一個庫.net
main.c
調用kernel函數debug
foo.cuh
code
參見https://blog.csdn.net/fb_help/article/details/79330815
須要注意的是,VS在debug模式下,應該把nvcc的flags中優化選項關閉掉。
技巧: 能夠把kernel函數作一層封裝,這樣一來在其餘.c/.cpp文件中,調用這個wrapper函數便可
e.g.
#include <stdio.h> #include <iostream> #include "foo.cuh" //注意包含頭文件 int main() { std::cout<<"Hello C++"<<std::endl; useCUDA(); // 這個函數是kernel函數的wrapper函數 return 0; }