花一些时间专注于NVIDIA提供的丰富文档。
从编程指南:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
这是一个如何分配内存简单的例子。现在,在你的内核,你应该接受一个指向浮动,像这样:
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x]++;
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= 0.3f;
}
所以现在你可以调用它们像这样:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
kernel1<<<1,128>>>(devPtr);
kernel2<<<1,128>>>(devPtr);
由于这些数据在众多 使用功能,我想它是全球性的 。
使用全局变量的原因很少。这绝对不是一个。我将把它作为一个练习来扩展这个例子,包括将“devPtr”移动到全局范围。
编辑:
好,最根本的问题是这样的:你的内核只能接入设备内存以及他们能够使用的唯一的全球范围的指针是GPU的。当从CPU调用内核时,幕后会发生什么,指针和原语在内核执行之前被复制到GPU寄存器和/或共享内存中。
所以我可以建议的最接近的是:使用cudaMemcpyToSymbol()来实现你的目标。但是,在背景中,考虑一种不同的方法可能是正确的。
#include <algorithm>
__constant__ float devPtr[1024];
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x] = devPtr[0] * devPtr[1];
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= devPtr[2];
}
int main(int argc, char *argv[])
{
float some_data[256];
for (int i = 0; i < sizeof(some_data)/sizeof(some_data[0]); i++)
{
some_data[i] = i * 2;
}
cudaMemcpyToSymbol(devPtr, some_data, std::min(sizeof(some_data), sizeof(devPtr)));
float* otherDevPtr;
cudaMalloc((void**)&otherDevPtr, 256 * sizeof(*otherDevPtr));
cudaMemset(otherDevPtr, 0, 256 * sizeof(*otherDevPtr));
kernel1<<<1,128>>>(otherDevPtr);
kernel2<<<1,128>>>(otherDevPtr);
return 0;
}
对于这个例子,不要忘记'--host-compilation = C++'。
看看也使用共享内存,global是设备内存层中最慢的。 – SpaceghostAli 2008-10-17 19:01:55
为什么要使用全局变量而不是将设备指针作为参数传递给内核?这样做只会给你在CPU代码中使用全局内存时的所有限制,几乎没有什么优势。 – 2012-04-26 23:07:16