【问题标题】:Why is the execution time for numpy faster than cupy?为什么numpy的执行时间比cupy快?
【发布时间】:2019-11-25 08:57:49
【问题描述】:

我正在研究 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.")

这里是cupy版本:

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。

【问题讨论】:

  • 从答案中澄清,此代码在 GPU 上所做的唯一工作是创建随机整数。其他一切都在 CPU 上,有许多小操作,只需将数据从 GPU 复制到 CPU。

标签: numpy cupy


【解决方案1】:
  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

【讨论】:

  • 这是有道理的。谢谢!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2012-01-22
    • 2014-05-28
    • 2019-12-14
    • 1970-01-01
    • 2013-08-24
    相关资源
    最近更新 更多