因此,我试图编写一些利用Nvidia的CUDA架构的代码。 我注意到复制到设备和从设备复制真的是在损害我的整体性能,所以现在我试图将大量数据移动到设备上。

由于这些数据用于众多功能,我希望它是全球性的。 是的,我可以传递指针,但我真的想知道在这个例子中如何使用全局变量。

所以,我有想要访问设备分配数组的设备功能。

理想情况下,我可以这样做:

__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调用,但我更喜欢动态分配方法。

===============>>#1 票数:5 已采纳

这样的事情应该可行。

#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;
}

给它一个旋转。

===============>>#2 票数:1

花些时间专注于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 ++'。

===============>>#3 票数:1

我继续尝试分配临时指针并将其传递给类似于kernel1的简单全局函数的解决方案。

好消息是它确实有效:)

但是,我认为它混淆了编译器,因为我现在得到“咨询:无论什么指针指向,假设全局内存空间”,每当我尝试访问全局数据时。 幸运的是,这个假设恰好是正确的,但警告很烦人。

无论如何,为了记录 - 我已经看了很多例子,并且确实贯穿了nvidia练习,其中的重点是让输出说“正确!”。 但是,我没有看过所有这些。 如果有人知道他们做动态全局设备内存分配的sdk示例,我仍然想知道。

===============>>#4 票数:0

由于这些数据用于众多功能,我希望它是全球性的。

-

使用全局变量的原因很少。 这肯定不是一个。 我将把它作为一个练习来扩展这个例子,包括将“devPtr”移到全局范围。

如果内核在由数组组成的大型const结构上运行会怎么样? 使用所谓的常量内存不是一种选择,因为它的大小非常有限..那么你必须把它放在全局内存中..?

===============>>#5 票数:0

嗯,这正是将devPtr移动到全局范围的问题,这是我的问题。

我有一个实现就是这样,两个内核都有一个指向传入数据的指针。我显然不希望传入这些指针。

我已经非常仔细地阅读了文档,并且点击了nvidia论坛(并且谷歌搜索了一个小时左右),但我还没有找到实际运行的全局动态设备数组的实现(我已经尝试了几个编译和然后以新的和有趣的方式失败)。

===============>>#6 票数:0

查看SDK附带的示例。 许多样本项目是一个体面的学习方式。

  ask by Voltaire translate from so

未解决问题?本站智能推荐:

1回复

CUDA-在内核中动态重新分配更多的全局内存

我对以下任务有疑问: “给出一个二维数组“ a [N] [M]”,因此N行的长度为M。该数组的每个元素都包含一个介于0到16之间的随机整数值。 listM,int * listN)“,它仅由N个线程的一个块组成,并且每个线程在数组的一行中计算有多少个元素的值为16。 线程将这些数字写
1回复

gpuocelot是否支持CUDA设备中的动态内存分配?

我的算法(并行多边高斯消除)需要在CUDA内核中动态分配内存(树结构)。 有谁知道gpuocelot是否支持这种东西? 据此: stackoverflow-link和CUDA编程指南我可以做这样的事情。 但是使用gpuocelot我在运行时会出错。 错误: 当我在内核中
1回复

使用C ++模板分配CUDA设备内存时发出警告

我声明了以下模板以使代码更短: 此外,我使用模板如下: float* alphaWiMinusOne; allocateGPUSpace<float>( alphaWiMinusOne,numUnigrams); 但是,当我编译代码时,VS 2008发出警告
4回复

CUDA中常量内存的动态分配

我正在尝试利用常量内存,但我很难搞清楚如何嵌套数组。 我所拥有的是一系列数据,这些数据包含内部数据,但每个条目的数据都不同。 所以基于以下简化代码我有两个问题。 首先,我不知道如何分配我的数据结构成员指向的数据。 其次,因为我不能使用cudaGetSymbolAddress来获取常量内存
1回复

cuda共享内存静态分配中的错误

我使用共享内存编写了CUDA代码,如下所示: 。 。 } 该代码有效,但是以下代码失败; 编译器在分配共享内存的行中期望常量。 它说(我忘记了确切的错误,但这是这样的): 参数应为常数 我能够使用printf并打印TILE的值,并且该值即将出现1.为
2回复

如何将展平的2D阵列从全局内存复制到CUDA中的共享内存

我有一个接收扁平化2D数组的内核,并且每次共享内存时我都希望复制该数组的一行,我的内核如下所示: 尽管当我验证x的值时,x的值一直在变化,或者随线程数变化。 例如,当20个250个线程的块根据执行结果返回值7或6时,500个线程的10个块返回9。 我想知道问题是来自共享内存中复制的2
1回复

如何将动态矩阵复制到CUDA中的设备存储器?

在我的代码中,我有动态矩阵。 我只想将其复制到设备全局内存一次。 我用过: 但这是行不通的。 我该怎么做?
2回复

如何减轻OpenCL / CUDA中的主机+设备内存传输瓶颈

如果我的算法由主机到设备和设备的瓶颈来承载内存传输,那么唯一的解决方案是不同的还是修改过的算法?
1回复

CUDA和cudamemcpy()中的固定内存

我了解到,当主机和设备之间的复制操作开始使用cudaMemcpy时,主机指针将自动固定。 那么,使用单独的API cudAHostAlloc()分配固定的主机内存的意义和必要性是什么?
1回复

全局内存写在CUDA中被认为是原子的吗?

全局内存写入是否在CUDA中被认为是原子的? 考虑以下CUDA内核代码: 全局内存是否写入globalStorage atomic ?,例如,没有竞争条件使并发内核线程写入存储在globalStorage中的同一变量的字节,这可能会导致结果混乱(例如,parial写入) ?