CUDA学习(二)-NVCC的编译过程及命令
nvcc编译过程第一篇:https://blog.csdn.net/shungry/article/details/89715468正文:编译流程(补充)以我mytest.cu为例子,输入以下命令:nvcc --cuda .\mytest.cu -keep先解释里面命令的含义,--cuda/-cuda是将.cu文件编译成一个.cu.cpp.ii的文件;--keep/-k...
nvcc编译过程第一篇:https://blog.csdn.net/shungry/article/details/89715468
正文:编译流程(补充)
以我mytest.cu为例子,输入以下命令:
nvcc --cuda .\mytest.cu -keep
先解释里面命令的含义,
--cuda/-cuda是将.cu文件编译成一个.cu.cpp.ii的文件;
--keep/-keep是指保留所有在中间层生成的文件;
在命令行中查看生成信息(或直接点开相应文件夹),出现以下结果:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019/4/30 14:31 1212818 mytest.cpp1.ii
-a---- 2019/4/30 14:31 294 mytest.cpp1.ii.res
-a---- 2019/4/30 14:31 1079606 mytest.cpp4.ii
-a---- 2019/4/30 14:31 244 mytest.cpp4.ii.res
-a---- 2019/4/28 20:18 2810 mytest.cu
-a---- 2019/4/30 14:31 1341211 mytest.cu.cpp.ii
-a---- 2019/4/30 14:31 175 mytest.cu.cpp.ii.res
-a---- 2019/4/30 14:31 274 mytest.cudafe1.c
-a---- 2019/4/30 14:31 654595 mytest.cudafe1.cpp
-a---- 2019/4/30 14:31 6664 mytest.cudafe1.gpu
-a---- 2019/4/30 14:31 1546 mytest.cudafe1.stub.c
-a---- 2019/4/30 14:31 4704 mytest.fatbin
-a---- 2019/4/30 14:31 13926 mytest.fatbin.c
-a---- 2019/4/30 14:31 27 mytest.module_id
-a---- 2019/4/30 14:31 2970 mytest.ptx
-a---- 2019/4/30 14:31 3496 mytest.sm_30.cubin
我们可以结合上一篇文章的图进行理解:https://blog.csdn.net/shungry/article/details/89715468
其中关注几个文件:
mytest.cpp1.ii为nvcc进行预处理时将.cu文件分离的device的部分;同理,mytest.cpp4.ii则是host端的代码部分(但文件中只有路径信息,我有点迷糊)。
mytest.ptx类似汇编用于device端的代码。
mytest.sm_30.cubin用于device端的二进制文件,由于我所用的电脑计算能力为3.0,所以编译二进制时自动编译为sm_30。
mytest.fatbin.c用于存放.cubin和.ptx的文件,如果你用vim查看文件,你会发现文件内只有一个数组,这应该就是是存.cubin/.ptx文件的地方:
static const __declspec(allocate(__CUDAFATBINDATASECTION)) unsigned long long fatbinData[]= {.../*这里省略*/...}
mytest.cuda1.*文件则是对以上文件的包含和调用,结合上一篇文章理解会更明白。
接下来输入以下命令:
nvcc mytest.cu -keep -dryrun
将会得到整个编译的过程:由于是vs编译环境起cl.exe就充当了C++ Preprocessor的功能,右边分支得到.cpp1.ii 。经过cicc进行编译成ptx文件。ptx在通过ptxas文件进行根据当前设备环境进一步的编译得到.cubin文件。最后创建fatbinary包括ptx和cubin文件,转化为.fatbin.c文件。(根据下面命令理解整个过程会更加清晰)
#$ cl.exe > "mytest.cpp1.ii" -D__CUDA_ARCH__=300 -nologo -E -TP -DCUDA_DOUBLE_MATH_FUNCTIONS -D__CUDACC__ -D__NVCC__ ......
#$ cicc --microsoft_version=1903 --msvc_target_version=1903 --compiler_bindir "......" --allow_managed -arch compute_30 -m64 -ftz=0 -prec_div=1 -prec_sqrt=1 -fmad=1 --include_file_name "mytest.fatbin.c" -tused -nvvmir-library "......" --gen_module_id_file --module_id_file_name "mytest.module_id" --orig_src_file_name "mytest.cu" --gen_c_file_name "mytest.cudafe1.c" --stub_file_name "mytest.cudafe1.stub.c" --gen_device_file_name "mytest.cudafe1.gpu" "mytest.cpp1.ii" -o "mytest.ptx"
#$ ptxas -arch=sm_30 -m64 "mytest.ptx" -o "mytest.sm_30.cubin"
#$ fatbinary --create="mytest.fatbin" -64 --cmdline="" "--image=profile=sm_30,file=mytest.sm_30.cubin" "--image=profile=compute_30,file=mytest.ptx" --embedded-fatbin="mytest.fatbin.c" --cuda
在左分支,也是先进行预处理得到mytest.cpp4.ii,再通过cudafe++将.cudafe1.stub.c和.cpp4.ii合成为.cudafe1.cpp,最后编译为.o/.obj文件。
#$ cl.exe > "mytest.cpp4.ii" -nologo -E -TP -D__CUDACC__ -D__NVCC__ "-IC:...... -D "__CUDACC_VER_BUILD__=176" -D "__CUDACC_VER_MINOR__=0" -D "__CUDACC_VER_MAJOR__=9" -FI "cuda_runtime.h" -EHsc "mytest.cu"
#$ cudafe++ --microsoft_version=1903 --msvc_target_version=1903 --compiler_bindir "......" --allow_managed --m64 --parse_templates --gen_c_file_name "mytest.cudafe1.cpp" --stub_file_name "mytest.cudafe1.stub.c" --module_id_file_name "mytest.module_id" "mytest.cpp4.ii"
#$ cl.exe -Fo"mytest.obj" -D__CUDA_ARCH__=300 -nologo -c -TP -DCUDA_DOUBLE_MATH_FUNCTIONS "......" -EHsc "mytest.cudafe1.cpp"
最后通过nvlink对多个.cubin文件进行链接存入fatbinary中,同样转化为.fatbin.c文件,最后组成link.stub文件。通过编译器进行编译,最后通过host链接器继续链接执行。
#$ nvlink --arch=sm_30 --register-link-binaries="a_dlink.reg.c" -m64 "......" -cpu-arch=X86_64 "mytest.obj" -o "a_dlink.sm_30.cubin"
#$ fatbinary --create="a_dlink.fatbin" -64 --cmdline="" -link "--image=profile=sm_30,file=a_dlink.sm_30.cubin" --embedded-fatbin="a_dlink.fatbin.c"
#$ cl.exe -Fo"a_dlink.obj" -nologo -c -TP -DFATBINFILE="\"a_dlink.fatbin.c\"" -DREGISTERLINKBINARYFILE="\"a_dlink.reg.c\"" -I. "......" -D "__CUDACC_VER_BUILD__=176" -D "__CUDACC_VER_MINOR__=0" -D "__CUDACC_VER_MAJOR__=9" -EHsc "......
#$ cl.exe -Fe"a.exe" -nologo "a_dlink.obj" "mytest.obj" -link -INCREMENTAL:NO "......devrt.lib cudart_static.lib
整体来说,我对细节部分把握的还是十分有限,但是结合上一篇的流程图理解起来就形象很多。
NVCC命令
nvcc的所有命令可以直接通过输入命令“ nvcc -h ”来查看,也可以通过查看nvcc官方文档,nvcc命令分为以下几种(是nvcc官方文档定义的):
1.File and Path Specifications:这个和平时的gcc编译选项很相似,如“-o”,“-l”,等。
2.Options for Specifying the Compilation Phase:这一类指定nvcc编译的输出,“-cuda”输出.ii文件
3.Options for Specifying Behavior of Compiler/Linker:让编译器执行相应功能,如“-g”就是提供debug信息,“-O”编译优化的等级
4.Options for Passing Specific Phase Options:
5.Options for Guiding the Compiler Driver:对nvcc的编译进行指导,如“-keep”,“-dryrun”只编译不执行
6.Options for Steering CUDA Compilation:???(--default-stream)指定命令发送到默认流上。
7.Options for Steering GPU Code Generation:生成gpu相关的命令,如“-arch”,“-code”
8.Generic Tool Options:一些帮助的工具“-V”,“-h”等
nvcc编译过程第三篇:https://blog.csdn.net/shungry/article/details/89842993
想了解更多可以直接看官方nvcc文档:https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)