我写了一个代码,每个GPU使用多个主机(OpenMP)线程。每个线程都有自己的CUDA流来定购请求。它看起来非常类似于下面的代码:CUDA 4.0 RC - 每个GPU有许多主机线程 - cudaStreamQuery和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 = 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之后调用cudaSuccess,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();
}
}
鉴于这是一个错误与功能问题,您最好在NVIDIA论坛上询问他们产品团队可以澄清它。 – 2011-03-08 14:58:51
@Ade:我做到了 - http://forums.nvidia.com/index.php?showtopic=194982 – kokosing 2011-03-08 15:01:35
你确定你已经在每个线程中正确初始化了cuda吗?你是否将正确的流传递给'cudaStreamSynchronize'(代码中没有参数)?另一方面,该流不必“准备就绪”来安排更多的内存传输和内核执行。这就是为什么它被称为流...... – LumpN 2011-03-08 17:33:24