题
所以,我尝试写某些代码,利用选的CUDA架构。我注意到,复制和设备是真的伤害了我的总体业绩,所以现在我想要移动的大量数据到设备。
作为这种数据是使用在许多职能,我希望它是全球性的。是的,我可以通过指针,但是我真的想知道如何与globals在这个实例。
因此,我已设备的功能要访问的设备分配阵列。
理想情况下,我可以做一些事情,如:
__device__ float* global_data;
main()
{
cudaMalloc(global_data);
kernel1<<<blah>>>(blah); //access global data
kernel2<<<blah>>>(blah); //access global data again
}
然而,我还没有想出如何创建一个动态阵列。我想出了一个工作围绕由宣布该阵列如下:
__device__ float global_data[REALLY_LARGE_NUMBER];
虽然这并不需要一个cudaMalloc打电话给我我会喜欢的动态分配的方法。
解决方案
像这样的东西也许应该的工作。
#include <algorithm>
#define NDEBUG
#define CUT_CHECK_ERROR(errorMessage) do { \
cudaThreadSynchronize(); \
cudaError_t err = cudaGetLastError(); \
if( cudaSuccess != err) { \
fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \
errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
exit(EXIT_FAILURE); \
} } while (0)
__device__ float *devPtr;
__global__
void kernel1(float *some_neat_data)
{
devPtr = some_neat_data;
}
__global__
void kernel2(void)
{
devPtr[threadIdx.x] *= .3f;
}
int main(int argc, char *argv[])
{
float* otherDevPtr;
cudaMalloc((void**)&otherDevPtr, 256 * sizeof(*otherDevPtr));
cudaMemset(otherDevPtr, 0, 256 * sizeof(*otherDevPtr));
kernel1<<<1,128>>>(otherDevPtr);
CUT_CHECK_ERROR("kernel1");
kernel2<<<1,128>>>();
CUT_CHECK_ERROR("kernel2");
return 0;
}
给它一个旋转。
其他提示
花一些时间集中在丰富的文件提供的更.
从编程指南:
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);
作为这种数据是使用众多的 职能,我希望它是 全球性的。
有几个好的理由使用globals.这绝对不是一个。我会把它作为一个运动来扩大这个例子包括移动"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;
}
不要忘了'--主编译=c++'这个例子。
我去了未来和试图解决的分配一个临时的指针和传递到一个简单的全球性功能类似于kernel1.
好消息是,它的工作:)
然而,我认为它混淆了编译器,因为我现在获得"咨询:不能告诉什么指点,假设全球的存储空间"每当我试着进入全球数据。幸运的是,假设是正确的,但这些警告是令人讨厌。
无论如何,为了记录在案-我已经看过很多的例子并没有运行,通过更练习的一点是得到输出说的"正确!".然而,我还没有看 所有 它们。如果有人知道的一个sdk例子,在那里他们做动态的全球性设备的存储器的分配,我仍然想要知道。
机构风险管理,这正是这个问题的运动devPtr全球范围这是我的问题。
我有一个实现不完全,与两个核具有一个指向数据传递。我明确地不想通过在这些指针。
我已经阅读了文件相当密切,并打上独的论坛(和谷歌搜索一个小时左右),但是我还没有找到一个实现的全球动态阵列设备实际运行(我已经尝试了几种汇编,然后失败的新的和有趣的方式).
检查出来的样本包括与软件开发工具包。许多的这些样本项目是一个体面的学习方式通过的例子。
作为这种数据是使用在许多职能,我希望它是全球性的。
-
有几个好的理由使用globals.这绝对不是一个。我会把它作为一个 行使扩大这种例子包括移动"devPtr"全球范围。
什么如果核心工作在大const结构组成的阵?使用所谓的常量存储器不是一个选项,因为它是非常有限的大小。所以然后你必须把它放在全球的存储器..?