4

2 つの CUBLAS API (例: cublasDgemm) を 2 つの cudaStream で実際に同時に実行したいと考えています。

私たちが知っているように、CUBLAS API は非同期であり、cublasDgemm のようなレベル 3 ルーチンはホストをブロックしません。つまり、次のコード (デフォルトの cudaStream 内) が同時に実行されます。

cublasDgemm();
cublasDgemm();

しかし、「NVIDIA Visual Profiler」でプログラムをプロファイリングすると、それらが正常に実行されていることがわかります。

次に、それらを異なる cudaStreams にバインドさせようとします。疑似コードは次のとおりです。

// Create a stream for every DGEMM operation
cudaStream_t *streams = (cudaStream_t *) malloc(batch_count*sizeof(cudaStream_t));
for(i=0; i<batch_count; i++)
    cudaStreamCreate(&streams[i]);

// Set matrix coefficients
double alpha = 1.0;
double beta  = 1.0;

// Launch each DGEMM operation in own CUDA stream
for(i=0; i<batch_count; i++){
    // Set CUDA stream
    cublasSetStream(handle, streams[i]);

    // DGEMM: C = alpha*A*B + beta*C
    cublasDgemm(handle,
                CUBLAS_OP_N, CUBLAS_OP_N,
                dim, dim, dim,
                &alpha,
                d_A[i], dim,
                d_B[i], dim,
                &beta,
                d_C[i], dim);
}

batch_count=5 の場合、「NVIDIA Visual Profiler」で表示される結果は次のとおりです。

マルチストリームでのマルチ CublasDegmm ルーチンの実行結果

結果は、それらがまだ正常に実行されていることを示しています。次のように、複数の cublas api を複数の cudaStreams で実際に同時に実行する方法:

マルチストリームによるマルチカーネル実行結果、それらは実際に同時に実行されます

誰にもアイデアはありますか?ありがとう。

4

1 に答える 1

3

まず、@Robert Crovella のコメントに感謝します。

@Robert Crovella のヘルプと私の調査によると、いくつかの特別なケースでは複数の CUBLAS API (例: cublasDgemm) を同時に実行できますが、ほとんどの場合は実行できません。

ケース 1:K40 で (m=n=k = 1024*8) の大きなディムで cublasDgemm を実行すると、プロファイラーは次のような結果を表示します。

ケース 2:K40 で (m=n=k = 64) の小さなディムで cublasDgemm を実行すると、プロファイラーは次のような結果を表示します。

ケース 3:しかし、K40 で (m=n=k = 256) の次元で cublasDgemm を実行すると、プロファイラーは次のように結果を表示します。

CASE 1 と CASE 2 の結果から、大きなディムだけでなく、小さなディムでも CUBLAS API を同時に実行できないことがわかります。ケース 1 の理由は、GPU リソースが使い果たされているため、別のルーチンを実行する余地が残っていないためです。ケース 2 の場合、2 つのカーネル起動のレイテンシが原因で、con を確認するのが困難になっています。

于 2017-01-03T03:51:11.143 に答える