使用Numba矢量化目标的负速度增益=';cuda&x27;

使用Numba矢量化目标的负速度增益=';cuda&x27;,cuda,anaconda,vectorization,numba,Cuda,Anaconda,Vectorization,Numba,我试图测试使用Python Numba模块的@vectorize decorator来加速与实际代码相关的代码片段的有效性。我正在使用CUDAcast#10中提供的代码片段,如下所示: import numpy as np from timeit import default_timer as timer from numba import vectorize @vectorize(["float32(float32, float32)"], target='cpu') def Vector

我试图测试使用Python Numba模块的@vectorize decorator来加速与实际代码相关的代码片段的有效性。我正在使用CUDAcast#10中提供的代码片段,如下所示:

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 decorator将大数组方程发送到gpu,从而获得100倍的加速。但是,当我将@vectorize目标设置为gpu时:

@vectorize(["float32(float32, float32)"], target='cuda')

。。。结果是速度慢了3-4倍。使用target='cpu'时,我的运行时间为0.048秒;使用target='cuda'时,我的运行时间为0.22秒。我使用的是戴尔Precision笔记本电脑,配有Intel Core i7-4710MQ处理器和NVIDIA Quadro K2100M GPU。运行nvprof(NVIDIA profiler tool)的输出表明,大部分时间都花在内存处理上(预期),但即使是函数求值在GPU上也比在CPU上的整个过程花费更长的时间。显然,这不是我所希望的结果,但这是由于我自己的错误,还是基于我的硬件和代码,这是合理的?

这个问题对我来说也很有趣。 我试过你的代码,得到了类似的结果。 为了调查这个问题,我使用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:]))
如果未计算复制时间:

GPU - 0.000245
所以,我学到的是,(1)从主机到设备以及从设备到主机的复制非常耗时。这是显而易见的,也是众所周知的。(2) 我不知道原因,但@vectorize可以显著降低GPU上的计算速度。(3) 最好使用自写内核(当然要尽量减少内存复制)

顺便说一下,我还通过显式有限差分格式求解热传导方程测试了@cuda.jit,发现在这种情况下,python程序的执行时间与C程序相当,并提供了大约100倍的加速。这是因为,幸运的是,在这种情况下,您可以在主机和设备之间进行多次迭代,而无需进行数据交换


UPD。使用的软件和硬件:Win7 64位,CPU:Intel Core2 Quad 3GHz,GPU:NVIDIA GeForce GTX 580。

Roman,感谢您的“健康检查”。我也感谢您的@cuda.jit代码。我是Numba和CUDA的新手,所以这将是我下一条探索的伟大道路!你能在帖子中添加你正在使用的硬件(处理器、GPU等)吗?
GPU - 0.000245