1 つの 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();
}
}