在 Fermi 架构上,CUDA 驱动程序使用 cmem[2] 来存储常量变量。同一模块中的所有函数共享相同的常量。这个常量库的大小不会影响您的理论 SM 占用率或增加您的启动开销。如果超过最大大小 (64KB),您应该会收到编译器错误。
CUDA 二进制实用程序 cuobjdump 可用于调试分配。
如果您的文件 sm20.cu 具有以下常量
__constant__ float k_float_array[] = { 0.f, 1.f, 2.f, 3.f };
__constant__ double k_double_array[] = { 0.0, 1.0, 2.0, 3.0 };
__constant__ int k_int_array[] = { 0, 1, 2, 3 };
__global__ void empty_kernel(float* a)
{
return;
}
你可以跑
cuobjdump.exe -elf sm20.cu.obj
可执行文件也可以用作参数。运行 cuobjdump --help 以获取选项列表。
此命令将产生以下输出
Fatbin elf code:
================
arch = sm_20
code version = [1,5]
producer = cuda
host = windows
compile_size = 32bit
identifier = c:/dev/constant/sm20.cu
32bit elf: abi=5, sm=20, flags = 0x140114
Sections:
Index Offset Size ES Align Type Flags Link Info Name
1 34 a6 0 1 STRTAB 0 0 0 .shstrtab
2 da e9 0 1 STRTAB 0 0 0 .strtab
3 1c4 80 10 4 SYMTAB 0 2 6 .symtab
4 244 18 0 4 CUDA_INFO 0 3 0 .nv.info
5 25c 20 0 4 CUDA_INFO 0 3 8 .nv.info._Z12empty_kernelPf
6 27c 24 0 4 PROGBITS 2 0 8 .nv.constant0._Z12empty_kernelPf
7 2a0 40 0 8 PROGBITS 2 0 0 .nv.constant2
8 2e0 10 0 4 PROGBITS 6 3 2000007 .text._Z12empty_kernelPf
elf 部分 .nv.constant2 包含 cmem[2] 的内容。这个大小是 0x40 == 64 字节,符合我的预期。
.nv.constant2 是节索引 7。
.section .strtab
.section .shstrtab
.section .symtab
index value size info other shndx name
0 0 0 0 0 0 (null)
1 0 0 3 0 8 .text._Z12empty_kernelPf
2 0 0 3 0 6 .nv.constant0._Z12empty_kernelPf
3 0 0 3 0 7 .nv.constant2
4 0 16 1 0 7 k_float_array
5 16 32 1 0 7 k_double_array
6 48 16 1 0 7 k_int_array
7 0 16 12 10 8 _Z12empty_kernelPf
.symtab 包含定义的 3 个常量数组。所有带有 shndx == 7 的符号都将在 .nv.constant2 中
.nv.constant0._Z12empty_kernelPf
0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
0x00000000 0x00000000 0x00000000 0x00000000
.nv.constant2
0x00000000 0x3f800000 0x40000000 0x40400000 0x00000000
0x00000000 0x00000000 0x3ff00000 0x00000000
0x40000000 0x00000000 0x40080000 0x00000000
0x00000001 0x00000002 0x00000003
.nv.constant2 定义节中的二进制数据。这与声明的常量变量匹配。如果您有很多常量,.symtab 部分会标识每个符号的偏移量和大小。
// skipping .nv.info and .text
cuobjdump 可用于转储 PTX 和 SASS 代码。PTX 和 SASS 程序集可用于确定哪些内核正在使用常量。