すべての GPU アクティビティ (特に実行中のすべてのスレッド) が確実に停止されるように、いくつかのコードを作成しようとしています。dlclose でモジュールをアンロードするには、これを行う必要があるため、ホストとデバイスの両方ですべてのスレッドが停止していることを確認する必要があります。
CUDA のドキュメントによると、cudaDeviceSynchronize:
デバイスが以前に要求されたすべてのタスクを完了するまでブロックします... cudaDeviceScheduleBlockingSync フラグがこのデバイスに設定されている場合、ホスト スレッドはデバイスがその作業を完了するまでブロックします。
ただし、ブロッキング同期フラグを設定して cudaDeviceSynchronize を呼び出すと、新しいホスト スレッドが生成され、cudaDeviceSynchronize が戻った後も実行されています。これは、私が達成しようとしていることの反対です。
この動作は、サンプル プログラムで示されています。
#include <iostream>
void initialiseDevice()
{
cudaError result = cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
if (cudaSuccess == result)
std::cout << "Set device flags." << std::endl;
else
std::cout << "Could not set device flags. (" << result << ")"
<< std::endl;
}
void synchroniseDevice()
{
cudaError result = cudaDeviceSynchronize();
if (cudaSuccess == result)
std::cout << "Device synchronise returned success." << std::endl;
else
std::cout << "Device synchronise returned error. (" << result << ")"
<< std::endl;
}
int main()
{
initialiseDevice();
sleep(1);
synchroniseDevice(); // new thread is spawned here
sleep(1); // new thread is still running here!
return 0;
}
このプログラムを でコンパイルしnvcc -g main.cu
、gdb で実行すると、 への呼び出しにより、info threads
cudaDeviceSynchronize が返された後に 2 つのスレッドが実行されていることが示されます。
gdb で実行中の cudaDeviceSynchronise の後の行の情報スレッドの出力:
(gdb) info threads
Id Target Id Frame
2 Thread 0x7ffff5b8b700 (LWP 28458) "a.out" 0x00007ffff75aa023 in select
() at ../sysdeps/unix/syscall-template.S:82
* 1 Thread 0x7ffff7fd4740 (LWP 28255) "a.out" main () at cuda_test.cu:30
cudaDeviceSynchronize が新しいスレッドを生成する理由と、呼び出しが戻った後もスレッドがまだ実行されている理由を理解できる人はいますか?
すべてのデバイスとホストのアクティビティ/スレッドが終了するまでブロックする方法を見つけるのを助けるために、誰かが私を正しい方向に向けることができますか?