【发布时间】:2016-03-01 05:08:11
【问题描述】:
我正在编写一个包含 cuda 内核的程序。我发现如果你使用#define OPERATOR *,一个线程将使用11个寄存器,但我你将使用#define OPERATOR /(除法运算符),一个线程将使用52个寄存器!怎么了?我必须
减少寄存器数量(我想设置maxregcount)!在 cuda 内核中使用 devision 运算符时如何减少寄存器数量?
#include <stdio.h>
#include <stdlib.h>
#define GRID_SIZE 1
#define BLOCK_SIZE 1
#define OPERATOR /
__global__ void kernel(double* array){
for (int curEl=0;curEl<BLOCK_SIZE;++curEl){
array[curEl]=array[curEl] OPERATOR 10;
}
}
int main(void) {
double *devPtr=NULL,*data=(double*)malloc(sizeof(double)*BLOCK_SIZE);
cudaFuncAttributes cudaFuncAttr;
cudaFuncGetAttributes(&cudaFuncAttr,kernel);
for (int curElem=0;curElem<BLOCK_SIZE;++curElem){
data[curElem]=curElem;
}
cudaMalloc(&devPtr,sizeof(double)*BLOCK_SIZE);
cudaMemcpy(devPtr,data,sizeof(double)*BLOCK_SIZE,cudaMemcpyHostToDevice);
kernel<<<1,BLOCK_SIZE>>>(devPtr);
printf("1 thread needs %d regs\n",cudaFuncAttr.numRegs);
return 0;
}
【问题讨论】:
-
如果你用
cuobjdump -dump-sass检查为内核生成的机器代码,你会发现双精度乘法是一个内置的硬件指令,而双精度除法是一个相当大的调用子程序,所以寄存器使用的一些扩展是可以预料的。然而,增加的幅度比我在类似情况下观察到的要大。这是发布版本吗?您可以使用__launch_bounds__属性在每个功能的基础上限制寄存器的使用。强制使用较低的寄存器可能会导致溢出,这也会降低性能。 -
这是调试版本。在实际构建中,我有 33 个用于 div 的 regs 和 6 个用于 mul 的 regs。我英语不好。你说gpu div不是一个简单的指令,它是一个函数?
-
正确的双精度除法在内部实现为调用的子例程(~= 函数),因为 GPU 中没有对浮点除法的直接硬件支持。您在发布版本中观察到的寄存器使用差异与我过去观察到的一致。
-
虽然不得不假设这不是问题的实际背景,但我想提一下将
/10更改为*0.1的选项。 -
@njuffa 你想提供答案吗?我会投票。
标签: cuda