为什么numpy的执行时间比cupy要快?

时间:2019-07-16 15:07:43

标签: numpy cupy

我正在研究numpy和cupy之间的差异,并且注意到在我创建的这两个类似程序中,cupup版本的运行速度要慢得多,尽管它是在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。

2 个答案:

答案 0 :(得分:2)

  1. 这是一个陷阱,吸引了许多GPU新手。朴素的GPU版本比CPU版本慢是很常见的。使用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

答案 1 :(得分:0)

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