繁体   English   中英

与cupy异步GPU内存传输

[英]Asynchronous GPU memory transfer with cupy

是否可以通过cupy (或chainer )从GPU异步传输内存?

我正在训练一个相对较小的网络,其数据非常大,不适合GPU内存。 此数据应保存在CPU内存中,并提供给GPU以按顺序进行小批量计算。

内存传输时间是此应用程序的主要瓶颈。 我认为异步内存传输解决了这个问题,即在计算一个小批量时,另一个小批量在后台转移到GPU。

我想知道它可以用cupy.cuda.Stream类,但我还不知道。 我将不胜感激任何意见/建议。

编辑:我认为以下代码进行异步内存传输,但不是。

import numpy as np
import cupy as cp

a_cpu = np.ones((10000, 10000), dtype=np.float32)
b_cpu = np.ones((10000, 10000), dtype=np.float32)

a_stream = cp.cuda.Stream(non_blocking=True)
b_stream = cp.cuda.Stream(non_blocking=True)

a_gpu = cp.empty_like(a_cpu)
b_gpu = cp.empty_like(b_cpu)

a_gpu.set(a_cpu, stream=a_stream)
b_gpu.set(b_cpu, stream=b_stream)

# This should start before b_gpu.set() is finished.
a_gpu *= 2

nvvp显示内存传输按顺序进行。

我通过深入了解chainer源代码找到了一个解决方案。

在构造np.ndarray时,一个关键点似乎是保留一个固定的内存缓冲区。

def pinned_array(array):
    # first constructing pinned memory
    mem = cupy.cuda.alloc_pinned_memory(array.nbytes)
    src = numpy.frombuffer(
                mem, array.dtype, array.size).reshape(array.shape)
    src[...] = array
    return src

a_cpu = np.ones((10000, 10000), dtype=np.float32)
b_cpu = np.ones((10000, 10000), dtype=np.float32)
# np.ndarray with pinned memory
a_cpu = pinned_array(a_cpu)
b_cpu = pinned_array(b_cpu)

a_stream = cp.cuda.Stream(non_blocking=True)
b_stream = cp.cuda.Stream(non_blocking=True)

a_gpu = cp.empty_like(a_cpu)
b_gpu = cp.empty_like(b_cpu)

a_gpu.set(a_cpu, stream=a_stream)
b_gpu.set(b_cpu, stream=b_stream)

# wait until a_cpu is copied in a_gpu
a_stream.synchronize()
# This line runs parallel to b_gpu.set()
a_gpu *= 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM