簡體   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