【问题标题】:CUDA constant memory value not correct [duplicate]CUDA 常量内存值不正确 [重复]
【发布时间】:2014-08-28 07:58:50
【问题描述】:

我一直在阅读许多与恒定记忆相关的 SO 问题,但我仍然不明白为什么我的程序无法正常工作。总体看起来如下

Common.cuh

__constant__ int numElements;

__global__
void kernelFunction();

Common.cu

#include "Common.cuh"
#include <stdio.h>

__global__
kernelFunction()
{
   printf("NumElements = %d", numElements);
}

Test.cu

#include "Common.cuh"

int main()
{
   int N = 100;
   cudaMemcpyToSymbol(numElements,&N,sizeof(int));
   kernelFunction<<<1,1>>>();
   cudaDeviceSynchronize();
   return 0;
}

它编译时没有错误,但是当打印numElements 的值时,我只是得到一个随机值。有人可以指出我正确的方向来理解这一点吗?

【问题讨论】:

    标签: cuda nvcc


    【解决方案1】:

    这一行:

    __constant__ int numElements;
    

    具有编译单元范围。这意味着如果你将它编译到一个模块中,也编译到另一个模块中,这两个模块将在__constant__ 内存中具有不同的numElements 实例化。

    解决方案是使用separate compilation and linking,将两个模块设备链接在一起,此时设备链接器将在两个模块之间解析符号。

    nvcc -arch=sm_20 -rdc=true -o test common.cu test.cu
    

    示例:

    $ cat common.cuh
    #ifndef COMMON_CU
    extern __constant__ int numElements;
    #endif
    __global__
    void kernelFunction();
    $ cat common.cu
    #define COMMON_CU
    #include "common.cuh"
    #include <stdio.h>
    
    __constant__ int numElements;
    __global__
    void kernelFunction()
    {
       printf("NumElements = %d\n", numElements);
    }
    $ cat test.cu
    #define TEST_CU
    #include "common.cuh"
    
    int main()
    {
       int N = 100;
       cudaMemcpyToSymbol(numElements,&N,sizeof(int));
       kernelFunction<<<1,1>>>();
       cudaDeviceSynchronize();
       return 0;
    }
    
    $ nvcc -arch=sm_20 -rdc=true -o test common.cu test.cu
    $ ./test
    NumElements = 100
    $
    

    【讨论】:

    • 当只有 Common.cu 使用常量变量 numElements 时,这可以正常工作。但是,如果我也想在 Test.cu 中使用常量变量,我会得到 nvlin error: Multiple definition of 'numElements'
    • 也许您应该仔细阅读答案并发布代码。 test.cu 确实 使用相同的常量变量,因为它正在写入常量变量,并且调用kernelFunction。多重定义错误是因为numElements只能在一个地方定义。其他任何地方都必须通过extern 引用它。请仔细阅读答案。
    • 请注意,我的答案与您的代码的区别在于 more 而不仅仅是编译命令。此外,我将头文件的numElements out 的定义移到了其中一个源文件(common.cu)中。在我的头文件 (common.cuh) 中,它仅通过 extern 引用 numElements,然后 如果该头文件包含在 common.cu 以外的文件中。所以我的答案和你的答案之间存在代码变化,而不仅仅是编译命令的差异。
    • 如标记的重复问题/答案中所示,也可以通过将numElements 的定义和所有显式引用移动到单个文件中来解决此问题。在其他文件(即编译单元或模块)中对numElements 的所有操作必须通过在定义numElements 的文件中定义的包装函数间接发生。该方法不需要模块之间的设备代码链接。
    • 对不起,我基本上不聊天。此外,我对 CMake 几乎一无所知。我的目的不仅仅是帮助,而是帮助其他可能通过谷歌或其他方式在 SO 上找到答案的人。 (聊天根本没有帮助。)由于您的基本示例有效,并且您现在收到的错误看起来完全不同,我建议发布一个新的 SO 问题。
    猜你喜欢
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多