4

我正在研究 numpy 和 cupy 之间的差异,并注意到在我创建的这两个类似程序中,cupy 版本要慢得多,尽管它是在 GPU 上运行的。

这是 numpy 版本:

import time
import numpy as np
size = 5000
upperBound = 20
dataSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
dataLength = np.random.randint(0, high=upperBound, size=size, dtype='l')
randomNumber = np.random.randint(0, high=62, size=size * upperBound, dtype='l')
count = 0
dataCount = 0
start_time = time.time()
for i in range(size):
    lineData = ""
    for j in range(dataLength[i]):
        lineData = lineData + dataSet[randomNumber[count]]
        count = count + 1
    print(lineData)
    dataCount = dataCount + 1
time = str(time.time() - start_time)
print("------------------------\n" + "It took this many sedonds: " + time)
print("There were " + str(dataCount) + " many data generations.")

这是杯子版本:

import time
import cupy as cp
size = 5000
upperBound = 20
dataSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
dataLength = cp.random.randint(0, high=upperBound, size= size,dtype='l')
randomNumber = cp.random.randint(0, high=62, size= upperBound * size,dtype='l')
count = 0
dataCount = 0
start_time = time.time()
for i in range(size):
    lineData = ""
    for j in range(int(dataLength[i])):
        lineData = lineData + str(dataSet[int(randomNumber[count])])
        count = count + 1
    print(lineData)
    dataCount = dataCount + 1
time = str(time.time() - start_time)
print("-------------------\n" +"It took this many seconds: " + time)
print("There were " + str(dataCount) + " many data generations.")

它们本质上是相同的代码,除了一个使用 numpy 而另一个使用 cupy。由于 GPU 的使用,我期望 cupy 执行得更快,但事实并非如此。numpy 的运行时间为:0.032。而 cupy 的运行时间是:0.484。

4

2 回答 2

6
  1. 这是一个让许多刚接触 GPU 的人陷入困境的陷阱。程序的原始 GPU 版本比 CPU 版本慢是很常见的。使用 GPU 使代码快速运行并非易事,主要是因为将数据复制到 GPU 和从 GPU 复制数据的额外延迟。无论您从使用 GPU 获得什么加速,都必须首先克服这种开销。您在 GPU 上做的工作还不够多,因此开销值得。您在 cp.random.randint() 调用中等待数据移动所花费的时间比您实际计算的时间要多得多。在 GPU 上做更多的工作,你会看到 GPU 负责,比如可能对大型数据集进行归约操作。

  2. Numpy 比您预期的要快得多,因为它是用经过良好优化的 C 语言编写的。它不是纯 Python。所以你试图超越的基准实际上是相当快的。

  3. 如果您真的想深入了解 GPU 性能调优,请尝试编写一些 CUDA 并使用 NVIDIA Visual Profiler 检查 GPU 实际在做什么。据说cupy对此有钩子,但我从未使用过它:https ://docs-cupy.chainer.org/en/stable/reference/cuda.html#profiler

于 2019-07-16T15:49:38.973 回答
0

我在这段代码中看不到用户定义的内核,因此它没有使用 GPU 进行任何权重矩阵计算。因此,将数据移入/移出 GPU 和类型转换的延迟可能占主导地位。

于 2019-08-16T21:51:25.847 回答