将 2D 数组复制到已知可变宽度的 GPU

2023-12-11

我正在研究如何将每行可变宽度的 2D 数组复制到 GPU 中。

int rows = 1000;
int cols;
int** host_matrix = malloc(sizeof(*int)*rows);
int *d_array;
int *length;

...

Each host_matrix[i]可能有不同的长度,我知道length[i],这就是问题开始的地方。我想避免复制虚拟数据。有更好的方法吗?

根据这个thread,这不是一个聪明的方法:

cudaMalloc(d_array, rows*sizeof(int*));  
for(int i = 0 ; i < rows ; i++)    {  
    cudaMalloc((void **)&d_array[i], length[i] * sizeof(int)); 
}  

但我想不出任何其他方法。还有其他更聪明的方法吗? 可以使用 cudaMallocPitch 和 cudaMemCpy2D 改进吗?


在 CUDA 中为 GPU 分配指针数组的正确方法是这样的:

int **hd_array, **d_array;
hd_array = (int **)malloc(nrows*sizeof(int*));
cudaMalloc(d_array, nrows*sizeof(int*));  
for(int i = 0 ; i < nrows ; i++)    {  
    cudaMalloc((void **)&hd_array[i], length[i] * sizeof(int)); 
}
cudaMemcpy(d_array, hd_array, nrows*sizeof(int*), cudaMemcpyHostToDevice);

(免责声明:在浏览器中编写,从未编译,从未测试,使用风险自负)

这个想法是你在中组装设备指针数组的副本host首先内存,然后将其复制到设备。对于 1000 行的假设情况,这意味着 1001 次调用cudaMalloc然后拨打 1001cudaMemcpy只需设置设备内存分配并将数据复制到设备中。那是一个enormous开销处罚,我建议不要尝试;表现将非常糟糕。

如果你有very锯齿状数据并且需要将其存储在设备上,我是否可以建议借鉴所有锯齿状数据问题的根源 - 大型、非结构化稀疏矩阵 - 并为您的数据复制一种稀疏矩阵格式。使用经典压缩稀疏行格式化为模型你可以这样做:

int * data, * rows, * lengths;

cudaMalloc(rows, nrows*sizeof(int));
cudaMalloc(lengths, nrows*sizeof(int));
cudaMalloc(data, N*sizeof(int));

在此方案中,将所有数据存储在单个线性内存分配中data。锯齿状数组的第 i 行开始于data[rows[i]]每行的长度为length[i]。这意味着您只需要三个内存分配和复制操作即可将任意数量的数据传输到设备,而不是nrows在你当前的计划中,即。它将开销从 O(N) 减少到 O(1)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 2D 数组复制到已知可变宽度的 GPU 的相关文章

随机推荐