如何将整数传送到__constant__设备内存?

时间:2012-06-16 22:30:34

标签: memory cuda

我有一个奇怪的问题,所以我想我会问,看看比我更有经验的人能否找到解决方案。

我正在用CUDA C / C ++编写一个程序,我有一些常量整数来指定各种各样的东西,比如计算边界的坐标等等。目前我只是将这些东西放在全局设备内存中。它们被每个内核调用中的每个线程访问,因此我认为如果它们在全局内存中,那么它们永远不会被缓存或广播(对吧?)。所以这些小整数占用了很多(相对)开销,并且有很多“读取冗余”。

所以我在标题中声明:

__constant__ int* number;

我包含那个标题,当我做内存时,我会这样做:

cutilSafeCall( cudaMemcpyToSymbol(number, &(some_host_int), sizeof(int) );

我将number传递给我的所有内核:

__global__ void magical_kernel(int* number, ...){

   //and I access 'number' like this
   int data_thingy = big_array[ *number ];

}

我的代码崩溃了。有了全局内存中的数字,就可以了。我已经确定它在访问内核中的数字时会崩溃。这意味着我正在访问或分配错误。如果它包含错误的值,它也会导致崩溃,因为它用于索引数组。

总而言之,我会问几个问题。首先,我做错了什么?作为奖励:有没有比常量内存更好的方法来完成这项任务 - 我不知道number在编译时的价值,所以一个简单的#define将不起作用。常量内存甚至可以加快代码的速度,还是一直在高速缓存和广播?我可以以某种方式将数据放在每个线程块的共享内存中,并通过多个内核调用将它保留在共享内存中吗?

1 个答案:

答案 0 :(得分:1)

这里有几个问题:

  1. 您已将number声明为指针,但从未为其分配一个值,该值是GPU内存中的有效地址
  2. 您有一个变量范围onflict:int * number 中定义的参数变量magic_kernel与定义为编译单元范围的__constant__ int * variable不是同一个变量
  3. cudaMemcpyToSymbol电话的第一个参数几乎肯定不正确。
  4. 如果你不明白为什么前两点中的任何一个都是真的,你可以对C ++中的指针和范围做一些修改。

    根据您对现已删除的答案的回复,我怀疑您实际上要做的是:

    __constant__ int number;
    
    __global__ void magical_kernel(...){
    
       int data_thingy = big_array[ number ];
    
    }
    
    cudaMemcpyToSymbol("number", &(some_host_int), sizeof(int));
    

    即。 number旨在成为常量内存中的整数,而不是指针,而不是内核参数。


    编辑:这是一个例子,显示了这一点:

    #include <cstdio>
    
    __constant__ int number;
    
    __global__ void magical_kernel(int * out)
    {
       out[threadIdx.x] = number;
    }
    
    int main()
    {
        const int value = 314159;
        const size_t sz = size_t(32) * sizeof(int);
        cudaMemcpyToSymbol("number", &value, sizeof(int));
    
        int * _out, * out;
    
        out = (int *)malloc(sz);
        cudaMalloc((void **)&_out, sz);
    
        magical_kernel<<<1,32>>>(_out);
    
        cudaMemcpy(out, _out, sz, cudaMemcpyDeviceToHost);
        for(int i=0; i<32; i++)
            fprintf(stdout, "%d %d\n", i, out[i]);
    
        return 0;
    }
    

    您应该能够自己运行并确认它的效果与宣传的一样。