私はいくつかのコードをプロファイリングしていますが、パフォーマンスの不一致を理解することはできません。私は2つの配列(インプレース)の間で単純な要素別の追加をしようとしています。これはnumbaを使ってCUDAカーネルです:Numba python CUDAとcuBLASの単純な操作での速度の差
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方法の性能が約25%高速であります大規模な配列(20M要素)の場合コンパイルされたPTXコードがすでにキャッシュされているので、これを呼び出すことでcuda.jit
カーネルを「ウォーミングアップ」した後です(この問題があるかどうかはわかりませんが、問題ではないことを確認するだけです)。
レベル3のマトリックスマトリックス操作でこのパフォーマンスの違いを理解できましたが、これは簡単な追加です。私はcuda.jitコードからより多くのパフォーマンスを絞るために何かできることはありますか?最適化したい実際のコードはblas.axpyに渡すことができない2次元配列なので、私は尋ねています。
EDIT実行コードやその他の必要なパッケージ:
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)
コードを投稿する場合は、少なくともコンパイルすることができますか?このような単純なカーネルでは、実行の引数はパフォーマンスにとって重要ですが、あなたはそれらを表示していません。これを修正していただけますか? – talonmies
これはあなたの実行の引数ですか?ブロックあたり64スレッド、1024ブロック? – talonmies
はい、私はTPBとブロックの他の組み合わせを試みました。 – user1554752