Performance 不能同时使用CumemCpYHTOASYNC和CumemCpYDTOASYNC

Performance 不能同时使用CumemCpYHTOASYNC和CumemCpYDTOASYNC,performance,cuda,gpu,jcuda,Performance,Cuda,Gpu,Jcuda,我对下面的代码片段有一个相当奇怪的观察 当我同时做这两件事时——将内存复制到设备并将结果复制回主机,流似乎是同步的——也就是说,它们按顺序执行内核。 一旦我删除复制到主机并将参数复制到设备,流将并行执行, 一旦我删除复制参数并继续复制结果,流也会并行执行 知道为什么吗?如何解决这个问题 for (int j=0; j<n_streams; j++) { cuMemcpyHtoDAsync(gpu_parameters[j], parameters[j].asPointer(), (

我对下面的代码片段有一个相当奇怪的观察

当我同时做这两件事时——将内存复制到设备并将结果复制回主机,流似乎是同步的——也就是说,它们按顺序执行内核。 一旦我删除复制到主机并将参数复制到设备,流将并行执行, 一旦我删除复制参数并继续复制结果,流也会并行执行

知道为什么吗?如何解决这个问题

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]);
}

for(int j=0;j不知道为什么…,但是更改序列消除了问题-并且正在并行执行

for (int j=0; j<n_streams; j++) {
    cuMemcpyHtoDAsync(gpu_parameters[j], parameters[j].asPointer(), (parameterCount) * Sizeof.FLOAT, stream[j]);
}
for (int j=0; j<n_streams; j++) {
    Pointer kernelParameters1 = Pointer.to(
            Pointer.to(new int[]{0}),
            Pointer.to(new int[] {getNPrices()}),
            Pointer.to(get_gpu_prices()),
            Pointer.to(gpu_results[j]),
            Pointer.to(gpu_parameters[j])
            //,Pointer.to(new int[]{0})
            );
    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
            );
}
for (int j=0; j<n_streams; j++) {
    cuMemcpyDtoHAsync(results[j].asPointer(), gpu_results[j], (results[j].size()) * Sizeof.FLOAT, stream[j]);
}

for(int j=0;jUnless)如果你有一个带有两个复制引擎的GPU,这是一个硬件限制,它无法在任何时候神奇地编程…即使内核的运行时间比复制所需的时间高1000倍?是:设备查询告诉我:“并发复制和内核执行:有1个复制引擎的情况下是”最终,两个相反方向的传输将互相阻塞,然后事情将序列化,直到两者都从流中弹出。如果您有两个dma引擎,则两个方向可能重叠,并将消除停滞。我仍然不清楚为什么会发生这种情况。使用一个流对内核进行相同数量的调用需要大约两倍的时间只要复制只在一个方向上进行,就比使用两个流进行复制要花更多的时间。似乎切换内存传输方向会实现设备同步…在排队系统中深度优先与广度优先的行为。我仍然想理解为什么内核在第一次尝试时被序列化。我的实际用途是不幸的是,se略有不同-在那里,我几乎无法控制向流中添加命令的顺序,因为每个流都有一个主机线程。因此,安排copyToDevice executeKernel copyToHost总是一个接一个地快速完成。流数:尝试2…10-始终存在相同的现象。关于使用每个流由一个单独的线程填充的情况:在调度cuMemcpyDtoHAsync之前,我添加了一个线程.sleep(),大约是内核执行的预期执行时间的60%,然后这些流(主要)并行运行。