我最近了解了NVCC如何为不同的计算架构编译CUDA设备代码.
根据我的理解,当使用NVCC的-gencode选项时,"arch"是程序员应用程序所需的最小计算体系结构,也是NVCC的JIT编译器将编译PTX代码的最小设备计算体系结构.
我也明白-gencode的"code"参数是NVCC完全编译应用程序的计算架构,因此不需要JIT编译.
在检查了各种CUDA项目Makefile之后,我注意到以下情况经常发生:
-gencode arch=compute_20,code=sm_20
-gencode arch=compute_20,code=sm_21
-gencode arch=compute_21,code=sm_21
Run Code Online (Sandbox Code Playgroud)
经过一些阅读,我发现可以在一个二进制文件中编译多个设备架构 - 在本例中为sm_20,sm_21.
我的问题是为什么需要这么多的arch/code对?以上是否使用了"拱"的所有值?
它之间的区别是什么?
-arch compute_20
-code sm_20
-code sm_21
Run Code Online (Sandbox Code Playgroud)
是自动选择"拱形"字段中最早的虚拟架构,还是存在其他一些模糊行为?
我应该注意其他任何编译和运行时行为吗?
我已经阅读了手册http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation,我仍然不清楚编译或运行时会发生什么.
我有一个 Dockerfile,它从源代码安装 PyTorch 库。
这是 Dockerfile 中的片段,它从 pytorch 源代码执行安装
RUN cd /tmp/ \
&& git clone https://github.com/pytorch/pytorch.git \
&& cd pytorch \
&& git submodule sync && git submodule update --init --recursive \
&& sudo TORCH_CUDA_ARCH_LIST="6.0 6.1 7.0 7.5 8.0" python3 setup.py install
Run Code Online (Sandbox Code Playgroud)
我对这里发生的事情没有正确的理解,希望得到社区的一些意见:
TORCH_CUDA_ARCH_LIST在这种情况下,它的作用是什么?我对 '-gencode' 语句中的 'code=sm_X' 选项有点困惑。
示例:NVCC 编译器选项有什么作用
-gencode arch=compute_13,code=sm_13
Run Code Online (Sandbox Code Playgroud)
嵌入库中?
只有与CC 1.3,或GPU的机器代码(代码的cubin)也与CC 1.3的GPU的PTX代码?
在“Maxwell 兼容性指南”中,声明“只有由 'code=' 子句指定的后端目标版本将保留在生成的二进制文件中”。
由此,我推断给定的编译器选项仅嵌入了带有 CC 1.3 且没有PTX 代码的GPU 的机器代码。这意味着,这将不能够运行这个库例如,AA麦克斯韦代卡上,因为是从机器代码可能是“刚刚在时间”(JIT)编译库中没有内嵌代码PTX。
另一方面,在 NVIDIA 的 GTC 2013 演示文稿“作为应用程序构建工具的 CUDA 工具包简介”中,它表示“-gencode arch=compute_13,code=sm_13”对于所有 CC >= 1.3 的 GPU 来说就足够了,并且对于 CC > 1.3 的 GPU 使用此编译器选项,机器代码是从 PTX 代码进行 JIT 化的。因此,在我看来,Maxwell 兼容性指南和 GTC 演示中给出的信息是相互矛盾的。
我的开发工作站目前有NVIDIA Quadro K2200和K620.两者都具有CUDA计算能力5.0.然而,最终的生产系统有一个Tesla K80,具有CUDA计算能力3.7.
是否可以在我的Quadro GPU上安装和开发用于计算能力的CUDA程序3.7,然后将它们移动到K80而无需进行重大更改?
这是demo.cu从 GPU 设备打印的目标:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
__global__ void hello_cuda() {
printf("hello from GPU\n");
}
int main() {
printf("hello from CPU\n");
hello_cuda <<<1, 1>>> ();
cudaDeviceSynchronize();
cudaDeviceReset();
printf("bye bye from CPU\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译并运行:
$ nvcc demo.cu
$ ./a.out
Run Code Online (Sandbox Code Playgroud)
这就是我得到的输出:
hello from CPU
bye bye from CPU
Run Code Online (Sandbox Code Playgroud)
问:为什么GPU没有打印结果?
看起来我确实错误配置了 cuda 工具包或其他东西,但是我可以从 cuda-samples 编译并运行各种程序。例如,matrixMul或deviceQuery
我在 Ubuntu 16.04 上。假设我得到了一个随机的 libtestcuda.so 文件,无论如何我可以检查编译库的 CUDA 计算兼容性吗?
我试过了
ll libtestcuda.so
Run Code Online (Sandbox Code Playgroud)
它没有显示太多。
我想知道这一点,因为如果我编译我的代码
-gencode arch=compute_30,code=sm_30;
Run Code Online (Sandbox Code Playgroud)
它在我编写的一个小型 cuda 程序上编译并运行良好,但是当我在我的 GPU 上运行 deviceQuery 时,它实际上显示了 CUDA 计算兼容性 3.5,所以我很想知道这段代码是否会在 3.0 或 3.5 架构中执行。
如果我编译并运行它
-gencode arch=compute_20,code=sm_20;
Run Code Online (Sandbox Code Playgroud)
或者
-gencode arch=compute_50,code=sm_50;
Run Code Online (Sandbox Code Playgroud)
它按预期失败。
如果我编译并运行它
-gencode arch=compute_35,code=sm_35;
Run Code Online (Sandbox Code Playgroud)
它按预期运行良好。