我一直在阅读与常量记忆相关的许多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
的值时,我只得到一个随机值。有人能指出我正确的方向来理解这个吗?
答案 0 :(得分:5)
这一行:
__constant__ int numElements;
有编译单元范围。这意味着如果将其编译为一个模块,也将其编译到另一个模块中,则这两个模块将在numElements
内存中具有__constant__
的不同实例。
解决方案是使用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
$