如何使多CUBLAS API(例如cublasDgemm)真正在多cudaStream中并发执行

时间:2016-12-30 03:40:51

标签: concurrency cuda cublas cuda-streams

我想让两个CUBLAS API(eg.cublasDgemm)真正在两个cudaStream中并发执行。

我们知道,CUBLAS API是异步的,像cublasDgemm这样的3级例程不会阻塞主机,这意味着以下代码(在默认的cudaStream中)将同时运行:

cublasDgemm();
cublasDgemm();

但是,当我使用" NVIDIA Visual Profiler" ,它表明它们有条不紊地运行。

然后,我尝试让它们绑定到不同的cudaStream,伪代码是:

// 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时,结果显示&#34; NVIDIA Visual Profiler&#34;是:

Multi-CublasDegmm Rountines Execution Result With Multi-Streams

结果显示它们仍然有序运行。如何在多cudaStream中同时运行多个cublas apis,如下所示:

Multi-Kernels Execution Result With Multi-Streams,They Run on Really Concurrnently

有人有任何想法吗?感谢。

1 个答案:

答案 0 :(得分:2)

首先,感谢@Robert Crovella的评论。

根据@Robert Crovella的帮助和我的研究,我们可以在某些特殊情况下同时运行多个CUBLAS API(例如cublasDgemm),但大多数情况下不能。

案例1:当我在K40上执行具有(d = n = k = 1024 * 8)大调光的cublasDgemm时,探查器会显示如下结果:cublasDgemm with dims of (M=N=K=1024*8)

案例2:当我在K40上执行带有(m = n = k = 64)小调光的cublasDgemm时,探查器会显示如下结果:cublasDgemm with dims of (M=N=K=64)

案例3:但是当我在K40上执行带有(m = n = k = 256)的dims的cublasDgemm时,探查器会显示如下结果: cublasDgemm with dims of (M=N=K=256)

从CASE 1和CASE 2的结果可以看出,我们不能同时运行CUBLAS API,不仅有大的dims和小的dims。情况1的原因是gpu资源已用完,因此没有剩余空间来运行另一个例程,而对于情况2,两个内核启动的延迟导致难以看到con。