分配两个调用cudaMalloc一次的数组
allocate two arrays calling cudaMalloc once
内存分配是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工具包的samples文件夹中,因此您可以假设h_A、h_B已正确启动,并且代码在没有我所做修改的情况下正常工作
结果是,第二个cudaMemcpy返回了一个错误,消息为无效参数。
操作"d_M+size"似乎不会返回人们所期望的结果,因为设备内存的行为不同,但我不知道是怎么回事。
有可能让我的方法(调用一次cudaMalloc为两个数组分配内存)发挥作用吗?欢迎就这是否是一个好方法发表任何意见/回答。
UPDATE
正如Robert和dreamcrash的回答所建议的那样,我必须向指针d_M添加元素数(numElements),而不是字节数。只是为了参考,没有明显的加速。
您只需要更换
float *d_B = d_M + size;
带有
float *d_B = d_M + numElements;
这是指针算术,如果您有一个浮点数组R = [1.0,1.2,3.3,3.4]
,您可以通过执行printf("%f",*R);
来打印它的第一个位置。第二个位置呢?你只需要做printf("%fn",*(++R));
,就可以做r[0] + 1
。你没有像以前那样做r[0] + sizeof(float)
。执行r[0] + sizeof(float)
时,您将访问自size(float) = 4
以来位于r[4]
位置的元素。
当您声明float *d_B = d_M + numElements;
时,编译器假设d_b
将在内存中连续分配,并且每个元素的大小将为float
。因此,您不需要以字节为单位指定距离,而是以元素为单位指定,编译器将为您计算。这种方法更人性化,因为用元素表示指针算术比用字节表示更直观。此外,它还更具可移植性,因为如果给定类型的字节数根据底层体系结构发生变化,编译器将为您处理。因此,一个人的代码不会因为假设了固定的字节大小而中断。
你说过"结果是,第二个cudaMemcpy返回了一个错误,其消息为无效参数">:
如果您打印与此错误相对应的数字,它将打印11
,如果您检查CUDA API,则验证此错误是否对应于:
cudaErrorInvalidValue
这表示传递给API的一个或多个参数调用不在可接受的值范围内。
在您的示例中,这意味着浮点*d_B = d_M + size;
超出了范围。
您已经为100000
浮点分配了空间,d_a
将从0开始到50000,但根据您的代码,d_b
将从numElements * sizeof(float);
开始50000*4=200000,因为200000>100000您将得到无效参数。
- 将二维数组的所有元素插入到一维数组中
- C++语法差异:二维和一维数组(指针算术)
- 将一维数组写入 CSV C++中的不同列?
- C++:将矩阵存储在一维数组中
- 如何在一维数组中的每个元素中都有多个int值
- 以C++填充一维数组
- 用于在一维数组上嵌套循环操作的正确 openmp 指令
- 如何在 <threads> c++ 中使用和一维数组进行矩阵乘法?
- C++按内存地址将多维数组更改为一维数组
- 在 c++ 中返回一维数组时出错
- 一维数组映射方式的性能差异问题
- 如何使用一维数组更改二维数组中的值?
- 使用二维数组作为一维数组是否正确?可能会导致未定义的行为左右?
- 将一维数组转换为二维数组
- 如何使用一维数组列表初始化二维数组
- 在一维数组中对二维进行排序
- 将一维数组的索引转换为二维数组
- 通过访问二维数组实现双线性插值的概念类似于一维数组
- 将二维数组传递到只需要一维数组的函数中(C++)
- 如何访问带有多个括号的一维数组以提高可读性