【发布时间】:2018-01-08 08:34:50
【问题描述】:
我正在尝试将对象传递给内核。这个对象基本上有两个变量,一个作为输入,另一个作为内核的输出。但是当我启动内核时,输出变量不会改变。但是当我向内核添加另一个变量并将输出值也分配给这个变量时,它突然对它们都有效。
我在另一个线程 (While loop fails in CUDA kernel) 中读到,如果内核不产生任何输出,编译器可以将内核评估为空以进行优化。
所以我作为唯一内核参数传递的这个输入/输出对象有可能没有被编译器以某种方式识别为输出?如果这是真的。有没有一种优雅的方法(我想避免添加另一个内核参数),例如可以防止这种情况的编译选项?
这是这个对象的类。
class Replica
{
public :
signed char gA[1024];
int MA;
__device__ __host__ Replica(){
}
};
这是一个基本上是求和的内核。
__global__ void sumKerA(Replica* Rd)
{
int t = threadIdx.x;
int b = blockIdx.x;
__shared__ signed short gAs[1024];
gAs[t] = Rd[b].gA[t];
for (unsigned int stride = 1024 >> 1; stride > 0; stride >>= 1){
__syncthreads();
if (t < stride){
gAs[t] += gAs[t + stride];
}
}
__syncthreads();
if (t == 0){
Rd[b].MA = gAs[0];
}
}
最后是我的主机代码。
int main ()
{
// replicas - array of objects
Replica R[128];
for (int i = 0; i < 128; ++i){
for (int j = 0; j < 1024; ++j){
R[i].gA[j] = 2*(rand() % 2) - 1;
}
R[i].MA = 0;
}
Replica* Rd;
cudaSetDevice(0);
cudaMalloc((void **)&Rd,128*sizeof(Replica));
cudaMemcpy(Rd,R,128*sizeof(Replica),cudaMemcpyHostToDevice);
dim3 DimBlock(1024,1,1);
dim3 DimGridA(128,1,1);
sumKerA <<< DimBlock, DimGridA >>> (Rd);
cudaThreadSynchronize();
cudaMemcpy(&R,Rd,128*sizeof(Replica),cudaMemcpyDeviceToHost);
// cudaMemcpy(&M,Md,128*sizeof(int),cudaMemcpyDeviceToHost);
for (int i = 0; i < 128; ++i){
cout << R[i].MA << " ";
}
cudaFree(Rd);
return 0;
}
【问题讨论】: