Memory 如何将整数传输到设备内存中?

Memory 如何将整数传输到设备内存中?,memory,cuda,Memory,Cuda,我有一个奇怪的问题,所以我想我会问一下,看看是否有比我更有经验的人能找到解决办法 我正在用CUDA C/C++编写一个程序,我有一些常量整数,用于指定各种内容,如计算边界的坐标等。。目前,我在全局设备内存中只有这些东西。它们被每个内核调用中的每个线程访问,所以我认为如果它们在全局内存中,那么它们就永远不会被缓存或广播(对吗?)。因此,这些小整数占用了大量(相对而言)开销,并且具有大量的“读取冗余” 因此,我在标题中声明: __constant__ int* number; 我包括那个标题,当我

我有一个奇怪的问题,所以我想我会问一下,看看是否有比我更有经验的人能找到解决办法

我正在用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
的值,所以简单的定义是行不通的。恒定内存是否会加快代码的速度,或者它是否一直被缓存和广播?我是否可以将每个线程块的数据放在共享内存中,并通过多个内核调用将其保留在共享内存中?

这里有几个问题:

  • 您已将
    number
    声明为指针,但从未为其分配GPU内存中的有效地址值
  • 变量作用域冲突:在
    magic\u内核
    中定义的参数变量
    int*number
    与定义为编译单元作用域的
    \uuuuuu常量\uuuuuuuu*变量
    不同
  • cudaMemcpyToSymbol
    调用的第一个参数几乎肯定是不正确的
  • 如果你不理解为什么前两个点都是真的,那么C++中的指针和作用域就有一些修改。

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

    __constant__ int number;
    
    __global__ void magical_kernel(...){
    
       int data_thingy = big_array[ number ];
    
    }
    
    cudaMemcpyToSymbol("number", &(some_host_int), sizeof(int));
    
    i、 e.
    number
    是常量内存中的整数,不是指针,也不是内核参数


    编辑:这是一个exmaple,它显示了这一点:

    #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;
    }
    
    #包括
    __恒定的整数;
    __全局内核(int*out)
    {
    out[threadIdx.x]=编号;
    }
    int main()
    {
    常数int值=314159;
    const size_t sz=size_t(32)*sizeof(int);
    cudaMemcpyToSymbol(“数字”&值,sizeof(int));
    int*_out,*out;
    out=(int*)malloc(sz);
    Cudamaloc((void**)和(u out,深圳));
    神奇的_内核(_out);
    cudaMemcpy(out、out、sz、cudaMemcpyDeviceToHost);
    
    对于(int i=0;i使用int而不是int*。谢谢!我之所以把数字作为参数,是因为我一直在研究将所有数据的引用传递给内核的方法。我仍然觉得字符串文字是cudaMemcpyToSymbol的第一个参数很奇怪;我不怀疑它的正确性,只是奇怪而已。没那么奇怪——API是g要从上下文符号表中获取变量的虚拟地址,这就是为什么参数是字符数组-用于查找。如果您知道,您也可以按地址传递符号。我尝试了您所说的,但程序仍然在memCpyToSymbol行中存在CUDA内存错误。唯一的方法是让它不出错s传递变量名而不是引号,这是一个纯整数。然后,当我尝试访问该数字时,该数字包含值0,这显然也是不正确的。这可能与该数字在三个单独的文件中定义、分配和使用有关吗(尽管分配和使用CUDA的文件中包含定义它的头文件)?CUDA不支持外部链接。我猜您可能有代码结构/编译问题。我已经编辑了我的答案,以包含一个完整的、可编译的、可运行的示例,说明它应该如何工作。