【问题标题】:Asynchronous GPU memory transfer with cupy使用 cupy 进行异步 GPU 内存传输
【发布时间】:2018-05-07 09:46:47
【问题描述】:

是否可以使用cupy(或chainer)从/向GPU异步传输内存?

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

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

我想知道cupy.cuda.Stream 类是否有可能,但我还不知道。 我将不胜感激任何 cmets/建议。

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

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 显示内存传输是按顺序进行的。

【问题讨论】:

    标签: python chainer cupy


    【解决方案1】:

    我通过深入了解chainer source code 找到了一种解决方案。

    在构造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
    

    【讨论】:

    • 如何检查两个操作是否并行运行?有没有办法对其进行剖析?
    • 为什么需要固定内存?看起来即使没有也可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2017-10-10
    • 2019-07-03
    • 2020-05-18
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    相关资源
    最近更新 更多