我正在从主机上的多媒体数据集中提取特征,我想在从所有图像中提取特征后执行一些处理任务。
特别是,我想执行一组操作,如距离计算和数据库索引或散列的预处理,可能在 GPU 上加速。但是,与顺序处理相比,传输大型特征数组的成本太高,并且会降低性能。
谁能建议一种方法来处理需要传输大型数据集的大型数据密集型任务?
我正在从主机上的多媒体数据集中提取特征,我想在从所有图像中提取特征后执行一些处理任务。
特别是,我想执行一组操作,如距离计算和数据库索引或散列的预处理,可能在 GPU 上加速。但是,与顺序处理相比,传输大型特征数组的成本太高,并且会降低性能。
谁能建议一种方法来处理需要传输大型数据集的大型数据密集型任务?
通过尝试使用异步内存副本和流来重叠内存传输和计算,可以隐藏传输大型数组的成本。
要完全理解如何,看一下 simpleStreams CUDA SDK 示例会非常有用。在这里,它只是勾画出总体思路。
让我们假设 GPU 必须通过一个名为的函数对两个长度为 的int
数组执行一些操作,a
并且这种操作的结果(同样长度为 )存储在数组中。假设创建流,并且每个流都对元素进行操作。更详细地说,每个流以长度的块加载和处理数据。让我们考虑以下代码(此代码仅用于说明,因为我没有测试过):b
M
__global__
kernel
M
c
2
stream0
stream1
M/2
M/4
for (int i=0; i<2; i++) {
cudaMemcpyAsync(d_a+i*M/4, h_a+i*M/4, (M/4)*sizeof(int), cudaMemcpyHostToDevice, stream0));
cudaMemcpyAsync(d_a+i*M/4+M/2, h_a+i*M/4+M/2, (M/4)*sizeof(int), cudaMemcpyHostToDevice, stream1));
cudaMemcpyAsync(d_b+i*M/4, h_b+i*M/4, (M/4)*sizeof(int), cudaMemcpyHostToDevice, stream0));
cudaMemcpyAsync(d_b+i*M/4+M/2, h_b+i*M/4+M/2, (M/4)*sizeof(int), cudaMemcpyHostToDevice, stream1));
kernel<<<(M/4)/256,256,0,stream0>>>(d_a+i*M/4, d_b+i*M/4, d_c+i*M/4);
kernel<<<(M/4)/256,256,0,stream1>>>(d_a+i*M/4+M/2, d_b+i*M/4+M/2, d_c+i*M/4+M/2);
cudaMemcpyAsync(h_c+i*M/4, d_c+i*M/4, (M/4)*sizeof(int), cudaMemcpyDeviceToHost, stream0));
cudaMemcpyAsync(h_c+i*M/4+M/2, d_c+i*M/4+M/2, (M/4)*sizeof(int), cudaMemcpyDeviceToHost, stream1));
}
为了说明起见,假设每个操作将花费相同的时间,那么内存传输和计算之间的重叠将类似于:
stream0 stream1
a H2D
a H2D
b H2D
kernel b H2D
c D2H kernel
c D2H
...
在这个例子中(其目的只是勾勒出总体思路),假设设备没有并发双向数据传输能力。当此功能可用时,其他方案可能会更有效。