gpt4 book ai didi

c++ - 分配两个数组一次调用 cudaMalloc

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:30 25 4
gpt4 key购买 nike

内存分配是 GPU 中最耗时的操作之一,因此我想通过使用以下代码调用一次 cudaMalloc 来分配 2 个数组:

int numElements = 50000;
size_t size = numElements * sizeof(float);

//declarations-initializations
float *d_M = NULL;
err = cudaMalloc((void **)&d_M, 2*size);
//error checking

// Allocate the device input vector A
float *d_A = d_M;


// Allocate the device input vector B
float *d_B = d_M + size;

err = cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
//error checking

err = cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
//error checking

原始代码位于名为 vectorAdd.cu 的 cuda 工具包的示例文件夹中,因此您可以假设 h_A、h_B 已正确启动并且代码无需我进行的修改即可工作。
结果是第二个 cudaMemcpy 返回错误消息 invalid argument

似乎操作“d_M + size”没有返回人们期望的结果,因为设备内存的行为不同但我不知道如何。

我的方法(调用一次 cudaMalloc 为两个数组分配内存)是否可行?也欢迎任何关于这是否是一个好方法的评论/回答。

更新
作为Robert的答案和 dreamcrash建议我必须将元素数 (numElements) 添加到指针 d_M 而不是字节数的大小。仅供引用,没有明显的加速。

最佳答案

你只需要更换

float *d_B = d_M + size;

float *d_B = d_M + numElements;

这是指针运算,如果你有一个 float 数组 R = [1.0,1.2,3.3,3.4] 你可以通过 printf("%f",*R);。而第二个位置?您只需执行 printf("%f\n",*(++R)); 从而 r[0] + 1。您不像以前那样执行 r[0] + sizeof(float)。当您执行 r[0] + sizeof(float) 时,您将访问位置 r[4] 中的元素,因为 size(float) = 4.

当您声明 float *d_B = d_M + numElements; 时,编译器假定 d_b 将在内存中连续分配,并且每个元素的大小为 float 。因此,您不需要以字节为单位指定距离,而是以元素为单位,编译器将为您计算。这种方法更人性化,因为用元素表示指针运算比用字节表示更直观。此外,它也更便携,因为如果给定类型的字节数根据底层架构发生变化,编译器会为您处理。因此,一个人的代码不会因为假定一个固定的字节大小而中断。


你说“结果是第二个 cudaMemcpy 返回了一个错误消息无效参数”:

如果您打印与此错误对应的数字,它将打印 11 并且如果您检查 CUDA API您确认此错误对应于:

cudaErrorInvalidValue

This indicates that one or more of the parameters passed to the APIcall is not within an acceptable range of values.

在您的示例中意味着 float *d_B = d_M + size; 超出了范围。

您已经为 100000 float 分配了空间,d_a 将从 0 开始到 50000,但是根据您的代码 d_b 将从 numElements * sizeof(float); 50000 * 4 = 200000,因为 200000 > 100000 你得到的是无效参数

关于c++ - 分配两个数组一次调用 cudaMalloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13685468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com