第一次写自己写cuda程序,就出现了访问冲突,求高手指点。
我编写了一个 光线跟踪 的cuda版本,就是想让每个线程处理得到(SCREEN_WIDTH=512) * (SCREEN_HEIGHT=512)屏幕上的一个像素点,得到颜色。
参数light_t, object_t传入到常量空间,返回512*512的颜色数组h_mem。
以下是关键代码
//////////////////////////////////////////////////////
//kernel
global void Render(unsigned char *o_mem)
{
// 得到该线程处理的元素的屏幕坐标
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
Ray ray;
ray.start = campos;
ray.dir = getUnitDirForImageCoords(x, y); // 调用device函数,求出每个屏幕像素对应的射线方向
float3 color = getColourForRay(ray); // 调用device函数,求出每根射线的颜色
color = clamp(color, 0.0, 1.0);
//???
//将对应颜色值直接写入到global memory
//考虑到合并访问,将o_mem分成等大小三部分,第一部分放r通道值,第二部分放g通道值,第三部分放b通道值。
// 可问题也出现在下面,说是访问冲突。我想应该没有超出范围才对呀。o_mem大小是SCREEN_WIDTHSCREEN_HEIGHT3
//个uchar。我哪里理解错了吗?
if(y < SCREEN_HEIGHT && x < SCREEN_WIDTH)
{
o_mem[ySCREEN_WIDTH + x] = unsigned char(color.x * 255);
o_mem[mem_size + ySCREEN_WIDTH + x] = unsigned char(color.y * 255);
o_mem[mem_size2 + ySCREEN_WIDTH + x] = unsigned char(color.z * 255);
}
}
//////////////////////////////////////////////////////
// 调用kernel的函数
void trace(float* object_t, float * light_t, unsigned char* h_mem)
{
// 分配显存空间
unsigned char* d_mem;
cutilSafeCall(cudaMalloc((void**) &d_mem, SCREEN_WIDTHSCREEN_HEIGHT3));
// 传值到常数空间
cutilSafeCall(cudaMemcpyToSymbol(object, object_t, sizeof(object_t)));
cutilSafeCall(cudaMemcpyToSymbol(light, light_t, sizeof(light_t)));
// 设置参数(让每一个thread对应一个像素点)
dim3 block(32,32);
dim3 threads(16,16);
// 调用kernel
Render<<<block, threads>>>(d_mem);
cutilCheckMsg(“Kernel execution failed”);
// 将处理结果拷贝到内存
cutilSafeCall(cudaMemcpy(h_mem, d_mem, mem_size*3, cudaMemcpyDeviceToHost ));
// 释放显存空间
cutilSafeCall(cudaFree(d_mem));
cudaThreadExit();
}