CUDA手册指定每个多处理器的 32位寄存器的数量。这是否意味着:
Double变量需要两个寄存器?
指针变量有两个寄存器吗? - 它必须是Fermi上不止一个具有6 GB内存的寄存器,对吗?
如果回答问题2是肯定的,那么使用较少的指针变量和更多int
索引一定更好。
电子。例如,这个内核代码:
float* p1; // two regs
float* p2 = p1 + 1000; // two regs
int i; // one reg
for ( i = 0; i < n; i++ )
{
CODE THAT USES p1[i] and p2[i]
}
理论上需要比这个内核代码更多的寄存器:
float* p1; // two regs
int i; // one reg
int j; // one reg
for ( i = 0, j = 1000; i < n; i++, j++ )
{
CODE THAT USES p1[i] and p1[j]
}
答案 0 :(得分:8)
对你的三个问题的简短回答是:
要扩展第3点,请考虑以下两个简单的内存复制内核:
__global__
void debunk(float *in, float *out, int n)
{
int i = n * (threadIdx.x + blockIdx.x*blockDim.x);
for(int j=0; j<n; j++) {
out[i+j] = in[i+j];
}
}
__global__
void debunk2(float *in, float *out, int n)
{
int i = n * (threadIdx.x + blockIdx.x*blockDim.x);
float *x = in + i;
float *y = out + i;
for(int j=0; j<n; j++, x++, y++) {
*x = *y;
}
}
根据您的计算,debunk
必须使用更少的寄存器,因为它只有两个本地整数变量,而debunk2
有两个额外的指针。然而,当我使用CUDA 5发布工具链编译它们时:
$ nvcc -m64 -arch=sm_20 -c -Xptxas="-v" pointer_size.cu
ptxas info : 0 bytes gmem
ptxas info : Compiling entry function '_Z6debunkPfS_i' for 'sm_20'
ptxas info : Function properties for _Z6debunkPfS_i
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 8 registers, 52 bytes cmem[0]
ptxas info : Compiling entry function '_Z7debunk2PfS_i' for 'sm_20'
ptxas info : Function properties for _Z7debunk2PfS_i
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info : Used 8 registers, 52 bytes cmem[0]
它们编译为完全相同的寄存器计数。如果您反汇编工具链输出,您将看到除了设置代码之外,最终的指令流几乎相同。这有很多原因,但它基本上归结为两个简单的规则: