我正在对一些代码进行性能分析,但无法解决性能差异。我试图在两个数组之间进行简单的逐元素加法(原地操作)。这是使用numba的CUDA内核:
from numba import cuda
@cuda.jit('void(float32[:], float32[:])')
def cuda_add(x, y):
ix = cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x
stepSize = cuda.gridDim.x * cuda.blockDim.x
while ix < v0.shape[0]:
y[ix] += x[ix]
ix += stepSize
我认为性能很好,但是与cuBLAS方法相比较后发现:
from accelerate.cuda.blas import Blas
blas = Blas()
blas.axpy(1.0, X, Y)
BLAS方法的性能对于大型数组(20M个元素)大约快了25%。这是在“热身”
cuda.jit
内核之后,先前调用它以使编译的PTX代码已经被缓存(不确定是否重要,但只是为了确保这不是问题)。我可以理解这种性能差异适用于三级矩阵-矩阵运算,但这只是一个简单的加法。有什么方法可以挤出更多的cuda.jit代码性能?我问这个问题是因为我想优化的真正代码是一个二维数组,无法传递给blas.axpy。
编辑执行代码和其他所需包:
import numpy as np
def main():
n = 20 * 128 * 128 * 64
x = np.random.rand(n).astype(np.float32)
y = np.random.rand(n).astype(np.float32)
## Create necessary GPU arrays
d_x = cuda.to_device(x)
d_y = cuda.to_device(y)
## My function
cuda_add[1024, 64](d_x , d_y)
## cuBLAS function
blas = Blas()
blas.axpy(1.0, d_x , d_y)