cuda - CUDA - 有没有办法在复制到 GPU 的同一内存中保留指向其他类的指针的相对性
问题描述
我正在使用代码,其中主机内存具有指向将由 cudaMemcpy 调用复制的其他内存区域的指针。
有没有办法在以下代码示例中执行类似的操作(这不起作用),以使设备内存指针中的元素与设备内存中的其他元素相对应,就像它们在主机内存中一样?还是有处理此类问题的“最佳实践”方式?
否则,我想我将不得不存储相对偏移量而不是指针。
#include "cuda_runtime.h"
#include <stdlib.h>
#include <stdio.h>
struct A {
A* nextA = nullptr;
int val = 5;
};
__global__ void kernel(A* d) {
d[0].nextA->val = 20;
}
int main() {
A* h = new A[2];
h[0].nextA = &h[1];
A* d;
cudaMalloc(&d, sizeof(A) * 2);
cudaMemcpy(d, h, sizeof(A) * 2, cudaMemcpyHostToDevice);
kernel << <1, 1 >> > (d);
cudaMemcpy(h, d, sizeof(A) * 2, cudaMemcpyDeviceToHost);
printf("val=%d\n",h[1].val); //hoping this would be 20
return 0;
}
解决方案
有没有办法......使设备内存指针中的元素与设备内存中的其他元素相对应,就像它们在主机内存中一样?
好吧,您可以使用 CUDA 的统一内存功能(自 CUDA 6 起可用),使用它您可以从主机端访问设备端内存,反之亦然。使用 Pascal 和更高版本的 GPU,您还可以获得虚拟内存分页,因此您可以分配比 GPU 实际拥有的更多的内存,并且仍然可以访问它。
当然,不经意地这样做会损害你的表现。非常小心地执行此操作仍会在某种程度上损害您的性能,而且我很难说有多少,因为这取决于用例,而且我不是 UVM + 分页类型的人。
还是有处理此类问题的“最佳实践”方式?
好吧,您可以使用偏移量而不是指针。您的相关指针可能共享某种常见的内存“竞技场”;如果他们还没有,您可能可以定义一个(在其中开始分配它们)。现在,停止存储指针。相反,将竞技场的基地址存储在某个公共位置,并从那里存储偏移量。然后在设备上分配竞技场大小的内存并复制您需要的内容。在设备端,您可以继续使用相同的代码,但使用设备端而不是主机端的 arena 地址。
...但实际上,这可能不是真正的答案。真正的答案很可能是:如果你经常取消引用指针,那么你的内核就有问题;重写它。它很可能被错误地设计为利用 GPU 的硬件,并且运行缓慢。
推荐阅读
- reactjs - 使用 Yii2 API 和 ReactJS 前端的 CORS 错误
- vba - VBA,倒数第二个“/”使用 InstrRev
- assembly - 为什么我不能访问堆栈的中间?
- firebase - 如果在firebase中将权限设置为true,则允许对用户具有写权限
- applepay - 沙盒上的 Bluesnap Apple Pay 钱包错误
- google-workspace - 团队存储库的团队云端硬盘与 Google 云端硬盘共享文件夹。Team Drive 目前值得吗?
- mongodb - MongoDB ODBC DSN 配置
- java - 尝试以特定方式从 StringBuilder 中删除多个特定字符
- c# - 将 onClick 添加到 Infragistics WebDataGrid
- python - AttributeError:“NoneType”对象在尝试添加多个 keras 密集层时没有属性“_inbound_nodes”