我有一个使用了17个寄存器的内核,如果将其减少到16个,那么100%的占用率就可以实现。我的问题是:除了完全重写我的算法之外,是否有方法可以减少使用的寄存器数量?我一直认为编译器比我聪明得多,所以例如仅出于清晰起见,我经常使用额外的变量。这种想法是错误的吗?
请注意:我知道--max_registers(或其语法)标志,但是使用本地内存将比降低25%的占用率更具有破坏性(我应该测试一下)。
我有一个使用了17个寄存器的内核,如果将其减少到16个,那么100%的占用率就可以实现。我的问题是:除了完全重写我的算法之外,是否有方法可以减少使用的寄存器数量?我一直认为编译器比我聪明得多,所以例如仅出于清晰起见,我经常使用额外的变量。这种想法是错误的吗?
请注意:我知道--max_registers(或其语法)标志,但是使用本地内存将比降低25%的占用率更具有破坏性(我应该测试一下)。
很难说,我认为nvcc编译器并不是很智能。
你可以尝试一些显而易见的方法,例如使用short代替int,通过引用传递和使用变量(例如&variable),展开循环,使用模板(如C++)。如果有除法、超越函数被连续应用,请尝试将它们作为一个循环。尽可能摆脱条件语句,可能会用冗余计算来代替它们。
如果您发布一些代码,也许您会得到具体的答案。
利用共享内存作为缓存可能会减少寄存器使用量并防止寄存器溢出到本地内存...
想象一下内核计算一些值,而这些计算出的值被所有线程使用,
__global__ void kernel(...) {
int idx = threadIdx.x + blockDim.x * blockIdx.x;
int id0 = blockDim.x * blockIdx.x;
int reg = id0 * ...;
int reg0 = reg * a / x + y;
...
int val = reg + reg0 + 2 * idx;
output[idx] = val > 10;
}
__global__ void kernel(...) {
__shared__ int cache[10];
int idx = threadIdx.x + blockDim.x * blockIdx.x;
if (threadIdx.x == 0) {
int id0 = blockDim.x * blockIdx.x;
cache[0] = id0 * ...;
cache[1] = cache[0] * a / x + y;
}
__syncthreads();
...
int val = cache[0] + cache[1] + 2 * idx;
output[idx] = val > 10;
}