【发布时间】:2012-04-01 04:18:26
【问题描述】:
我正在尝试追踪寄存器的使用情况,并遇到了一个有趣的场景。考虑以下来源:
#define OL 20
#define NHS 10
__global__ void loop_test( float ** out, const float ** in,int3 gdims,int stride){
const int idx = blockIdx.x*blockDim.x + threadIdx.x;
const int idy = blockIdx.y*blockDim.y + threadIdx.y;
const int idz = blockIdx.z*blockDim.z + threadIdx.z;
const int index = stride*gdims.y*idz + idy*stride + idx;
int i = 0,j =0;
float sum =0.f;
float tmp;
float lf;
float u2, tW;
u2 = 1.0;
tW = 2.0;
float herm[NHS];
for(j=0; j < OL; ++j){
for(i = 0; i < NHS; ++i){
herm[i] += in[j][index];
}
}
for(j=0; j<OL; ++j){
for(i=0;i<NHS; ++i){
tmp = sum + herm[i]*in[j][index];
sum = tmp;
}
out[j][index] = sum;
sum =0.f;
}
}
作为对源代码的附注 - 我可以做 += 的运行总和,但正在研究如何改变寄存器使用的影响(似乎没有 - 只是添加了一个额外的 mov 指令)。 此外,此源面向访问映射到 3D 空间的内存。
根据声明计算寄存器,似乎有 22 个寄存器(我相信 float[N] 占用 N+1 个寄存器 - 如果我错了,请纠正我)。
但是编译:
nvcc -cubin -arch=sm_20 -Xptxas="-v" src/looptest.cu
产量:
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 25 registers, 72 bytes cmem[0]
好的,所以数字与“预期”不同。此外,如果使用 :
编译nvcc -cubin -arch=sm_13 -Xptxas="-v" src/looptest.cu
寄存器使用量远少 - 准确地说是 8 个(显然是因为 sm_20 比 sm_13 更符合 IEEE 浮点数学标准?):
ptxas info : Compiling entry function '_Z9loop_testPPfPPKfS2_4int3i' for 'sm_13'
ptxas info : Used 17 registers, 40+16 bytes smem, 8 bytes cmem[1]
最后,将宏 OL 更改为 40,然后突然:
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 28 registers, 72 bytes cmem[0]
总之,我想知道寄存器在哪里被吃掉了,以及我所做的几个观察结果是什么。
我没有足够的组装经验来通过 cuobjdump - 答案肯定隐藏在那里 - 也许有人可以告诉我我应该寻找什么或向我展示如何处理组装的指南转储。
【问题讨论】:
-
会不会是您的循环被编译器为值为 20 的 OL 展开,而在 40 时没有展开?
-
我认为 Ashwin 的评论是正确的。此外,您应该考虑通过扭曲级别添加案例来展平循环总和,如 CUDA C 编程指南中所述。 developer.download.nvidia.com/compute/DevZone/docs/html/C/doc/…
-
我非常有信心寄存器计数的差异与浮点、循环展开或到目前为止提到的任何其他内容无关。请记住,sm_20 内部是 64 位架构,而 sm_13 是 32 位架构。这意味着与 sm_12 相比,为 sm_20 编译的指针的寄存器占用量是 sm_12 的两倍。
-
尽管指针的宽度是原来的两倍,但它们仍然应该算作单个寄存器,不是吗?此外,我相信循环已展开,因为在编译时已知数字范围并且不会有分歧 - 但我必须使用
#pragma unroll测试该理论,看看它们是否不同。 -
64 位指针(或任何 64 位值)每个都需要 2 个寄存器,因为寄存器是 32 位的。但是@talonmies,指针大小不取决于是否指定了
-m32或-m64`?我不记得哪个是默认值;可能默认匹配当前的操作系统。
标签: c optimization cuda