我正在尝试测试使用Python Numba模块的@vectorize装饰器加速与我的实际代码相关的代码片段的有效性。我正在使用CUDAcast#10中提供的代码段here,如下所示:
import numpy as np
from timeit import default_timer as timer
from numba import vectorize
@vectorize(["float32(float32, float32)"], target='cpu')
def VectorAdd(a,b):
return a + b
def main():
N = 32000000
A = np.ones(N, dtype=np.float32)
B = np.ones(N, dtype=np.float32)
C = np.zeros(N, dtype=np.float32)
start = timer()
C = VectorAdd(A, B)
vectoradd_time = timer() - start
print("C[:5] = " + str(C[:5]))
print("C[-5:] = " + str(C[-5:]))
print("VectorAdd took %f seconds" % vectoradd_time)
if __name__ == '__main__':
main()
在CUDAcast的演示中,演示者通过@vectorize装饰器将大阵列方程式发送到gpu,从而获得100倍的加速。但是,当我将@vectorize目标设置为gpu:
时@vectorize(["float32(float32, float32)"], target='cuda')
......结果慢了3-4倍。使用target ='cpu',我的运行时间为0.048秒;使用target ='cuda'我的运行时间为0.22秒。我正在使用配备Intel Core i7-4710MQ处理器和NVIDIA Quadro K2100M GPU的DELL Precision笔记本电脑。运行nvprof(NVIDIA分析器工具)的输出表明大部分时间花费在内存处理(预期)上,但即使功能评估在GPU上花费的时间也比整个过程在CPU上花费的时间长。显然这不是我希望的结果,但这是由于我的一些错误还是基于我的硬件和代码这是合理的?
答案 0 :(得分:1)
这个问题对我来说也很有趣。 我已经尝试过您的代码并获得了类似的结果。 以某种方式调查此问题,我使用cuda.jit编写了CUDA内核并将其添加到您的代码中:
import numpy as np
from timeit import default_timer as timer
from numba import vectorize, cuda
N = 16*50000 #32000000
blockdim = 16, 1
griddim = int(N/blockdim[0]), 1
@cuda.jit("void(float32[:], float32[:])")
def VectorAdd_GPU(a, b):
i = cuda.grid(1)
if i < N:
a[i] += b[i]
@vectorize("float32(float32, float32)", target='cpu')
def VectorAdd(a,b):
return a + b
A = np.ones(N, dtype=np.float32)
B = np.ones(N, dtype=np.float32)
C = np.zeros(N, dtype=np.float32)
start = timer()
C = VectorAdd(A, B)
vectoradd_time = timer() - start
print("VectorAdd took %f seconds" % vectoradd_time)
start = timer()
d_A = cuda.to_device(A)
d_B = cuda.to_device(B)
VectorAdd_GPU[griddim,blockdim](d_A, d_B)
C = d_A.copy_to_host()
vectoradd_time = timer() - start
print("VectorAdd_GPU took %f seconds" % vectoradd_time)
print("C[:5] = " + str(C[:5]))
print("C[-5:] = " + str(C[-5:]))
在这个&#39;基准&#39;我还考虑了从主机到设备以及从设备到主机复制阵列的时间。在这种情况下,GPU功能比CPU 1慢。
对于上述情况:
CPU - 0.0033;
GPU - 0.0096;
Vectorize (target='cuda') - 0.15 (for my PC).
如果没有计算复制时间:
GPU - 0.000245
所以,我所学到的,(1)从主机到设备以及从设备到主机的复制非常耗时。这是显而易见的,众所周知的。 (2)我不知道原因,但@vectorize可以显着减慢GPU的计算速度。 (3)最好使用自编写的内核(当然最小化内存复制)。
顺便说一下,我还通过显式有限差分方案解决了热传导方程,测试了@ cuda.jit,发现在这种情况下,python程序的执行时间与C程序相当,提供了大约100倍的加速。这是因为,幸运的是,在这种情况下,您可以进行多次迭代,而无需在主机和设备之间进行数据交换。
UPD。二手软件&amp;硬件:Win7 64bit,CPU:Intel Core2 Quad 3GHz,GPU:NVIDIA GeForce GTX 580。