我认为CUDA会尝试在寄存器中分配标量变量,而在Fermi类GPU中,每个线程都有63个寄存器。 我的代码是这样的:
__global__ void test20 (double a)
{
double i1=1.0;
double i2=2.0;
double i3=3.0;
double i4=4.0;
double i5=5.0;
double i6=6.0;
double i7=7.0;
double i8=8.0;
double i9=9.0;
double i10=10.0;
...
a = i1+i2+i3 ... i20
}
但是当我看到每个线程使用NVVP的寄存器数量时,我只看到每个线程分配2个寄存器,当我预期更高的数字时。即使我将变量减少到10,分配的寄存器数量仍然相同。为什么会发生这种情况,如何确保我有n个变量,CUDA使用n个寄存器(考虑到每个变量可以存储在一个寄存器中)?
编辑:
根据建议,我修改了这样的代码:
__global__ void test (double *a)
{
double reg1;
double reg2;
double reg3;
double reg4;
double reg5;
double reg6;
double reg7;
double reg8;
....till 40
reg1 = log10f(a[0]);
reg2 = log10f(a[1]);
reg3 = log10f(a[2]);
reg4 = log10f(a[3]);
reg5 = log10f(a[4]);
reg6 = log10f(a[5]);
reg7 = log10f(a[6]);
reg8 = log10f(a[7]);
reg9 = log10f(a[8]);
....till 40
a[0] = reg1;
a[1] = reg2;
a[2] = reg3;
a[3] = reg4;
a[4] = reg5;
a[5] = reg6;
a[6] = reg7;
a[7] = reg8;
}
我memcpy
- 将数组a
返回给主机。我现在看到每个线程使用所有63个寄存器:ptxas info : Used 62 registers, 40 bytes cmem[0]
。虽然我通过了很多
在寄存器中可以容纳的变量,我没有看到任何溢出到本地存储器;我认为NVCC正在优化代码以仅使用寄存器。
答案 0 :(得分:1)
如果您遵循@talonmies建议使用无法在运行时评估的表达式,您可能仍然无法获得每个声明的寄存器(或者在这种情况下,2个寄存器用于保存双精度)。您可能还必须在此期间保持变量处于活动状态。
__global__ void test20 (double a)
{
double i1=1.0 * a;
double i2=2.0 * i1;
double i3=3.0 * i2;
double i4=4.0 * i3;
double i5=5.0 * i4;
a = i1+i2+i3+i4+i5;
printf("a = %f = %f + %f + %f + %f + %f\n", a, i1, i2, i3, i4, i5);
}
这是用浏览器编写的示例代码。目标是将值保留在寄存器中。此示例没有实际应用,因为编译器的目标是使用最少的寄存器。这里唯一的值是调试,以便在变量范围内使变量保持活动状态。
如果你想了解寄存器用法,你应该使用cuobjump -sass来转储内核的汇编代码。