我正在尝试使用CUDAcast#10中提供的代码片段here来测试使用Python Numba模块's @vectorize decorator for speeding up a code snippet relevant to my actual code. I' m的有效性,如下所示:
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上花费的时间长 . 显然这不是我希望的结果,但这是由于我的一些错误还是基于我的硬件和代码这是合理的?
1 回答
这个问题对我来说也很有意思 . 我已经尝试过您的代码并获得了类似的结果 . 以某种方式调查此问题我使用cuda.jit编写了CUDA内核并将其添加到您的代码中:
在这个“基准”中,我还考虑了从主机到设备以及从设备到主机复制阵列的时间 . 在这种情况下,GPU功能比CPU 1慢 .
对于上述情况:
如果没有考虑复制时间:
所以,我所学到的,(1)从主机到设备以及从设备到主机的复制非常耗时 . 这是显而易见的,众所周知的 . (2)我不知道原因,但@vectorize可以显着减慢GPU的计算速度 . (3)最好使用自编写的内核(当然最小化内存复制) .
顺便说一下,我还通过显式有限差分方案解决了热传导方程,测试了@ cuda.jit,发现在这种情况下,python程序执行时间与C程序相当,并提供大约100倍的加速 . 这是因为,幸运的是,在这种情况下,您可以进行多次迭代,而无需在主机和设备之间进行数据交换 .
UPD . 二手软件和硬件:Win7 64bit,CPU:Intel Core2 Quad 3GHz,GPU:NVIDIA GeForce GTX 580 .