将指向设备__constant__内存的指针传递给内核,而不是直接使用

时间:2013-02-28 19:12:48

标签: pointers memory cuda constants

我在ubuntu 12.10和gcc 4.6上使用CUDA 5.0和GTX 670,我编写了一个名为Grid的类:

https://github.com/benadler/octocopter/blob/master/basestation/grid.cu

https://github.com/benadler/octocopter/blob/master/basestation/grid.cuh

Grid-class正在另外两个类中使用:

  • pointcloudcuda
  • 粒子系统

现在我想在pointcloudcuda和粒子系统的内核中使用Grid的(非静态)方法,即使它们将使用不同的网格(具有不同值的不同网格对象)。因此,对于我使用Grid的所有类,我有两个选择:

1)我只是做

Grid hostGrid(...);
cudaMalloc(gridOnDeviceGlobal, sizeof(Grid))
cudaMemcpy(gridOnDeviceGlobal, &hostGrid, sizeof(Grid), cudaMemcpyHostToDevice)
cloudKernel<<< numBlocks, numThreads >>>(someDate, gridOnDeviceGlobal);

这很简单,但内核必须从全局内存中读取网格值。这可能很慢。

2)由于网格值很少改变,我放了一个

__constant__ Grid myGridForPointCloudCuda

进入pointcloudcuda.cu,连同两个函数

void copyParametersToGpu(Grid *hostGrid)
{
    cudaMemcpyToSymbolAsync(myGridForPointCloudCuda, hostGrid, sizeof(Grid))
}

void getDevicePointerOfGridForPointCloudCuda(Grid** ptr)
{
    cudaGetSymbolAddress((void**)ptr, myGridForPointCloudCuda);
}

现在,在pointcloudcuda.cpp中,我可以

Grid hostGrid(...);
copyParametersToGpu(&hostGrid);
Grid* gridOnDeviceConstant;
getDevicePointerOfGridForPointCloudCuda(&gridOnDeviceConstant);
cloudKernel<<< numBlocks, numThreads >>>(someDate, gridOnDeviceConstant);

在我看来,2)的优点是可以更快地访问内核中的常量内存。但是在其他地方,我读到这不起作用,因为编译CUDA内核的编译器在编译时不知道传递的网格指针是指向全局内存还是常量内存,因此必须使用较慢存储器取指令。

在Geforce GTX 670上2)会比1)快吗?

有没有更好的方法来做我想要的?我只需要将不同的Grid实例传递给内核。在我开始使用多个Grid-instance之前,常量变量是一个舒适且快速的选择。

谢谢!

1 个答案:

答案 0 :(得分:1)

如果您有多个Grid实例而不是简单地在常量内存中分配Grid数组,请将Grid实例复制到数组中,并在调用内核时将索引传递给Grid Array而不是指向特定Grid实例的指针。在内核中使用索引来访问特定的Grid实例。