只有使用 cupy 的 GPU 到 CPU 传输速度非常慢

Posted

技术标签:

【中文标题】只有使用 cupy 的 GPU 到 CPU 传输速度非常慢【英文标题】:Only GPU to CPU transfer with cupy is incredible slow 【发布时间】:2021-12-18 14:23:58 【问题描述】:

如果我在 GPU 上有一个数组,那么复制回一个形状数组 (20, 256, 256) 真的很慢(数百秒)。

我的代码如下:

import cupy as cp
from cupyx.scipy.ndimage import convolve
import numpy as np

# Fast...
xt = np.random.randint(0, 255, (20, 256, 256)).astype(np.float32)
xt_gpu = cp.asarray(xt)

# Also very fast...
result_gpu = convolve(xt_gpu, xt_gpu, mode='constant')

# Very very very very very slow....
result_cpu = cp.asnumpy(result_gpu)

我使用cp.cuda.Event()recordsynchronize 来测量时间以避免测量任何随机时间,但结果仍然相同,GPU->CPU 传输速度非常慢。但是,使用 PyTorch 或 TensorFlow 时并非如此(对于类似的数据大小/形状没有经验)......我做错了什么?

【问题讨论】:

【参考方案1】:

我想你可能是在计时错误。我修改了代码以在每个 GPU 操作之间进行同步,看起来卷积占用了大部分时间,两个传输操作都非常快。

import cupy as cp
from cupyx.scipy.ndimage import convolve
import numpy as np
import time
# Fast...
xt = np.random.randint(0, 255, (20, 256, 256)).astype(np.float32)

t0 = time.time()
xt_gpu = cp.asarray(xt)
cp.cuda.stream.get_current_stream().synchronize()
print(time.time() - t0)

# Also very fast...
t0 = time.time()
result_gpu = convolve(xt_gpu, xt_gpu, mode='constant')
cp.cuda.stream.get_current_stream().synchronize()
print(time.time() - t0)

# Very very very very very slow....
t0 = time.time()
result_cpu = cp.asnumpy(result_gpu)
cp.cuda.stream.get_current_stream().synchronize()
print(time.time() - t0)

输出:

0.1380000114440918
4.032999753952026
0.0010001659393310547

在我看来,当您测试它时,您实际上并没有在调用之间进行同步。在传输回 numpy 数组之前,所有操作都只是排队,并且似乎在没有同步调用的情况下立即完成。这将导致测量的 GPU->CPU 传输时间实际上是卷积和传输的时间。

【讨论】:

以上是关于只有使用 cupy 的 GPU 到 CPU 传输速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章

如何将 CuPy 数组传输到 tensorflow

理解 CUDA、Numba、Cupy 等的扩展示例

减少 CPU 到 GPU 数据传输延迟的技术

Cupy的用处概述

如何指示 CuPy 在 GPU 中同时运行多个相同的作业?

如何在 Cupy 中使用多个 GPU?