我编写了一个代码,每个 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();
}
}