4

我想让两个 CUBLAS API(例如.cublasDgemm)真正在两个 cudaStreams 中同时执行。

众所周知,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”显示的结果是:

Multi-CublasDegmm Routines 多流执行结果

结果表明,它们仍然有序地运行。如何使多个 cublas api 在多个 cudaStreams 中真正同时运行,如下所示:

多流的多内核执行结果,它们真正并发运行

有人知道吗?谢谢。

4

1 回答 1

3

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

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

案例 1:当我在 K40 上执行具有 (m=n=k=1024*8) 的大尺寸的 cublasDgemm 时,分析器显示结果如下:具有 (M=N=K=1024*8) 的尺寸的 cublasDgemm

案例2:当我在K40上执行cublasDgemm with small dims of (m=n=k=64)时,分析器显示结果如下:cublasDgemm with dims of (M=N=K=64)

案例 3:但是当我在 K40 上执行暗度为 (m=n=k=256) 的 cublasDgemm 时,分析器显示结果如下: 暗度为 (M=N=K=256) 的 cublasDgemm

从 CASE 1 和 CASE 2 的结果可以看出,我们不能同时运行 CUBLAS API,不仅是大尺寸和小尺寸。case 1 的原因是 gpu 资源已经用完,所以没有空间运行其他例程,而 case 2 是两个内核启动的延迟导致很难看到 con。

于 2017-01-03T03:51:11.143 回答