CUDA 4.0 RC - 每个GPU的许多主机线程 - cudaStreamQuery和cudaStreamSynchronize行为

时间:2011-03-08 14:48:40

标签: cuda openmp cuda-streams

我写了一个代码,每个GPU使用许多主机(OpenMP)线程。每个线程都有自己的CUDA流来订购它的请求。它看起来非常类似于下面的代码:

#pragma omp parallel for num_threads(STREAM_NUMBER)
for (int sid = 0; sid < STREAM_NUMBER; sid++) {
    cudaStream_t stream;
    cudaStreamCreate(&stream);

    while (hasJob()) {

        //... code to prepare job - dData, hData, dataSize etc

        cudaError_t streamStatus = cudaStreamQuery(stream);
        if (streamStatus == cudaSuccess) {
             cudaMemcpyAsync(dData, hData, dataSize, cudaMemcpyHostToDevice, stream);
             doTheJob<<<gridDim, blockDim, smSize, stream>>>(dData, dataSize);
        else {
             CUDA_CHECK(streamStatus);
        }
        cudaStreamSynchronize(stream);
    }
    cudaStreamDestroy(stream);
}

在我找到许多小工作之前,一切都很顺利。在这种情况下,cudaStreamQuery会不时返回cudaErrorNotReady,这对我来说意外,因为我使用的是cudaStreamSynchronize。到目前为止,我认为如果在cudaStreamSynchronize之后调用cudaStreamQuery,它将始终返回cudaSuccess。不幸的是,即使cudaStreamQuery仍然返回cudaErrorNotReady,cudaStreamSynchronize似乎也可能完成。

我将代码更改为以下内容,一切正常。

#pragma omp parallel for num_threads(STREAM_NUMBER)
for (int sid = 0; sid < STREAM_NUMBER; sid++) {
    cudaStream_t stream;
    cudaStreamCreate(&stream);

    while (hasJob()) {

        //... code to prepare job - dData, hData, dataSize etc

        cudaError_t streamStatus;
        while ((streamStatus = cudaStreamQuery(stream)) == cudaErrorNotReady) {
             cudaStreamSynchronize();
        }
        if (streamStatus == cudaSuccess) {
             cudaMemcpyAsync(dData, hData, dataSize, cudaMemcpyHostToDevice, stream);
             doTheJob<<<gridDim, blockDim, smSize, stream>>>(dData, dataSize);
        else {
             CUDA_CHECK(streamStatus);
        }
        cudaStreamSynchronize(stream);
    }
    cudaStreamDestroy(stream);
}

所以我的问题是......它是一个错误还是一个功能?

编辑:它类似于JAVA

synchronize {
    while(waitCondition) {
         wait();
    }
}

2 个答案:

答案 0 :(得分:2)

下的内容
//... code to prepare job - dData, hData, dataSize etc

你有没有cudaMemcpyAsync种类的功能,或者你所展示的代码中只有内存传输?即使代码不在目的地,这些异步函数也可能提前退出。发生这种情况时,cudaStreamQuery仅在内存传输成功时返回cudaSuccess

此外,hasJob()是否使用任何主机CUDA功能?

如果我没有弄错,在单个流中,不可能同时执行内核和内存传输。因此,仅当内核依赖于由不同流传输的数据时,才需要调用cudaStreamQuery

答案 1 :(得分:1)

之前没有注意到:cudaStreamSynchronize()应该使用参数(stream)。当参数被省略时,我不确定您正在同步哪个流,可能是默认为流0。