-gencode=arch=compute_30,code="sm_30,compute_30"
这句话中,compute_30出现了两次?
我说说我的理解:
-gencode : 后面出现的这一串字符用来指定嵌入的kernel代码,包括二进制和PTX。这一命令可以出现多次,每一次指定一个arch
arch=compute_30:这一指令用于生成计算能力3.0代码。也就是说,如果程序运行在3.0或者以上设备上,就装载这个指令生成的代码
code="sm_30,compute_30" :这个就是我看不懂的地方了,compute_30 是嵌入为3.0设备优化的 二进制代码? sm_30意思是同时嵌入为3.0设备优化的PTX指令的意思吗?如果嵌入的二进制代码过时了,就自动用这些PTX重新生成。
那么,如果我加一句“ -gencode=arch=compute_30,code="sm_11,compute_10" ”(当然这一句不好)
是不是就会是这样的:如果运行在3.0设备上,就使用嵌入的1.0二进制代码,如果这个二进制代码过时了,就用嵌入的1.1 PTX代码重新编译?
:lol:lol:lol
同时也说明
假如说我搞一句
-gencode=arch=compute_10,code="sm_30,compute_30"
那么程序运行在1.0设备上肯定是要出问题的?因为它根本不支持3.0代码……
楼主您好,
您需要知道一点基本的当前device code的编译流程,得先是编译出ptx文件,然后再根据ptx文件编译出cubin文件。
而这个流程实际上是分成2步的:
(1)CUDA C/C++ → PTX (根据虚拟架构编译)
(2)PTX → CUBIN(根据真实架构编译)
你的命令行的-arch和-code,(你的-gencode=…是他们的合并形式)
前者只影响根据虚拟架构编译出的东西。
而后者则只影响将要被嵌入的是什么东西。
举个例子:
例子1:
nvcc -arch=compute_10 -code=compute_10 a.cu
将你源代码编译出1.0的ptx,并在你最终的a.exe中嵌入的也是1.0的ptx(你的a.exe将不包含cubin)
例子2:
nvcc -arch=compute_10 -code=sm_10 a.cu
将你源代码编译出1.0的ptx,并在你最终的a.exe中嵌入的是1.0的cubin(将自动提前执行一次ptx到cubin的编译)。你最终的a.exe将不含有ptx文件(中间编译的ptx文件被丢弃了)。你的a.exe将严格只能运行在1.0的硬件上。
例子3:
nvcc -arch=compute_10 -code=sm_10,sm_11,sm_12,sm_13,sm_30,sm_35,compute_10 a.cu
将你源代码编译出1.0的ptx,并在你最终的a.exe中嵌入的是1.0到3.5的各种cubin。同时还被嵌入到你的exe的是1.0的ptx(方便你将来运行在4.x之类的计算能力上)
例子4:(也就是你要求的解释的例子)
-arch=compute_10 -code=sm_30,compute_30
将会导致编译失败,因为中途编译出的是1.0的ptx,你却要求嵌入3.0的cubin和3.0的ptx,cubin虽然可以从1.0的ptx编译出,但3.0的ptx却目前没有直接的转换过程(你刚才要求的是1.0的ptx)。这是无意义的,将不能通过编译。
因为这个无意义,无法通过编译,所以你要求的运行效果的描述也无法给出(无exe啊。亲)
简单的说,
-arch决定了编译(源代码到ptx)
-code决定了嵌入(ptx或者cubin的嵌入,cubin将自动从ptx转换来)
感谢周末来访。
以及补充下,你的失败的例子中,必须改成-arch compute_*和后面的-code里的compute_*完全相同才可以的。
因为上步编译只有1个ptx出来,能嵌入的也只有这个ptx,必须一样。
而不能编译出的是猫,要求嵌入的是老虎。
感谢周末来访。