我正在尝试跟踪寄存器使用情况,并遇到了一个有趣的场景。考虑以下源代码:
#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 - 答案肯定埋在其中 - 也许有人可以告诉我该寻找什么或向我展示如何处理汇编转储的指南。