我是CUDA的新手,我正在尝试用NUMBA \ CUDA来加速我的代码 . 但是,我遇到了一些麻烦,因为我的代码非常慢 . 示例代码如下所示 .
from timeit import default_timer as timer
from numba import jit, guvectorize, int32, int64, float64
from numba import cuda
@cuda.jit
def f_vec_loops(x, ret, maxiter):
nx = len(ret)
ny = len(ret[0])
for k in range(maxiter):
for i in range(nx):
for j in range(ny):
ret[i, j] += x[i, j]
x = 1024
y = 1024
a = np.ones([x, y], dtype='int32')
ret = np.zeros([x, y], dtype='int32')
a_cuda = cuda.to_device(a)
ret_cuda = cuda.to_device(ret)
maxiter = 100
s = timer()
cuda.synchronize()
f_vec_loops(a_cuda, ret_cuda, maxiter)
cuda.synchronize()
print(timer() - s)
s = timer()
trt = ret_cuda.copy_to_host()
print(trt)
print(timer()-s)
代码的输出是后续的:
24.132136431649194
[[100 100 100 ..., 100 100 100]
[100 100 100 ..., 100 100 100]
[100 100 100 ..., 100 100 100]
...,
[100 100 100 ..., 100 100 100]
[100 100 100 ..., 100 100 100]
[100 100 100 ..., 100 100 100]]
0.03437229066477343
正如您所看到的,与问题的复杂性相关的结果时间是巨大的 . 我试图隔离单个GPU功能,结果时间非常小:
0.1956893293540045
我实现了这个取消“cuda.synchronize()”,所以在某种程度上必须连接到线程的同步 . 但是,我不知道如何解决这个问题 . 欢迎任何帮助!
1 回答
这里有两个基本错误 - 您的内核是完全串行的,并且您正在运行一个线程 . 您通过删除
cuda.synchronize()
看到的明显加速只是改变您测量的结果 . 内核启动API是异步的,因此删除同步调用只是意味着您只测量内核启动时间,而不是总内核执行时间 .您的内核可以通过以下方式进行简单修改:
跑步时你会看到类似的东西:
与原始(完全串行)代码相比,它提供了大约200倍的加速 .
在CUDA中编写并行代码的基本概念在书籍,教程,博客,Stack Overflow问题以及工具包文档本身中有详细描述 . Numba Python CUDA语言非常忠实地复制了基本CUDA C语言的子集,从CUDA C学习CUDA Python的障碍非常低 . 您需要做的就是阅读 .