【发布时间】:2020-09-22 00:54:04
【问题描述】:
我对下面的代码 sn-p 有一个相当奇怪的观察。
当我两者都做时 - 将内存复制到设备并将结果复制回主机时,流似乎是同步的 - 即它们按顺序执行内核。 一旦我将副本删除到主机并将参数复制到设备,流将并行执行, 一旦我删除复制参数并继续复制结果,流也会并行执行。
知道为什么吗?以及如何解决这个问题?
for (int j=0; j<n_streams; j++) {
cuMemcpyHtoDAsync(gpu_parameters[j], parameters[j].asPointer(), (parameterCount) * Sizeof.FLOAT, stream[j]);
Pointer kernelParameters1 = Pointer.to(
Pointer.to(new int[]{0}),
Pointer.to(new int[] {10000}),
Pointer.to(gpu_data),
Pointer.to(gpu_results[j]),
Pointer.to(gpu_parameters[j])
);
cuLaunchKernel(function[j],
s_grid, 1, 1, // Grid dimension
s_block, 1, 1, // Block dimension
0, stream[j], // Shared memory size and stream
kernelParameters1, null // Kernel- and extra parameters
);
cuMemcpyDtoHAsync(results[j].asPointer(), gpu_results[j], (results[j].size()) * Sizeof.FLOAT, stream[j]);
}
【问题讨论】:
-
除非你有一个带有两个复制引擎的 GPU,否则这是一个硬件限制,不能神奇地编程
-
哦...即使内核的运行时间是复制所需时间的 1000 倍?
-
是的:设备查询告诉我:“并发复制和内核执行:是的,有 1 个复制引擎”
-
最终,两个相反方向的传输将相互阻塞,然后事情将序列化,直到两者都从流中弹出。如果您有两个 dma 引擎,那么两个方向可以重叠并且将消除失速
-
这对我来说仍然不明显,为什么会发生这种情况。只要复制只在一个方向上完成,使用 1 个流对内核进行相同数量的调用所花费的时间大约是使用 2 个流的两倍。似乎切换内存传输方向会进行设备同步....
标签: performance cuda gpu jcuda