スレッド数が多い時、CPU使用率が非常に高くなる。
Closed this issue · 6 comments
PostgreSQLの並列クエリを有効にすると、iostatで見たスループットが、並列クエリ=disabled である場合と比べて顕著に低下する。
perfで調べてみたところ、CUDAの中から呼ばれている pthread_rwlock_rdlock
でCPU時間を大量に消費している。
これが原因で、おそらくスループットの低下を招いている。
Samples: 6M of event 'cycles', Event count (approx.): 4941230366343, Thread: postgres
Children Self Command Shared Object Symbol
+ 92.17% 0.00% postgres libcuda.so.535.104.05 [.] 0x00007fe7feab100c a
+ 59.43% 0.00% postgres libpthread-2.28.so [.] __GI___pthread_rwlock_rdlock (inlined) a
+ 59.42% 0.00% postgres libcuda.so.535.104.05 [.] 0x00007fe7fee3af37 a
- 59.34% 59.34% postgres libpthread-2.28.so [.] __pthread_rwlock_rdlock a
59.33% __GI___clone (inlined) a
start_thread a
gpuservGpuWorkerMain a
- gpuservHandleGpuTaskExec a
◆ - 58.61% 000000000000ce58 a
◆ - 58.61% 000000000000ce58 a
◆ - 58.61% 000000000000ce58 a
◆ 0x7fe7fee3af37 a
◆ - __GI___pthread_rwlock_rdlock (inlined) a
◆ __pthread_rwlock_rdlock_full (inlined) a
◆ + 0.72% gpuservLoadKdsArrow (inlined) a
◆ 59.27% 0.00% postgres libpthread-2.28.so [.] __pthread_rwlock_rdlock_full (inlined) a
◆ __pthread_rwlock_rdlock_full (inlined)
◆ 20.49% 0.00% postgres libpthread-2.28.so [.] __GI___pthread_rwlock_unlock (inlined) a
- 20.48% 0.00% postgres libcuda.so.535.104.05 [.] 00007fe7fee3b12b a
- 00007fe7fee3b12b a
+ 20.48% __GI___pthread_rwlock_unlock (inlined) a
- 20.46% 20.46% postgres libpthread-2.28.so [.] __pthread_rwlock_unlock a
20.45% __GI___clone (inlined) a
start_thread a
gpuservGpuWorkerMain a
◆ - gpuservHandleGpuTaskExec a
- 20.21% 000000000000dc61 a
- 20.21% 000000000000dc61 a
- 20.21% 000000000000dc61 a
0x7fe7fee3b12b a
+ __GI___pthread_rwlock_unlock (inlined) a
+ 20.35% 0.00% postgres libpthread-2.28.so [.] __pthread_rwlock_rdunlock (inlined) a
+ 4.06% 0.00% postgres libcufile.so.1.7.2 [.] 0x00007fe7fe0b95a6 a
+ 4.06% 0.00% postgres libcuda.so.535.104.05 [.] 0x00007fe7fec65d6c a
+ 4.06% 0.00% postgres libcuda.so.535.104.05 [.] 0x00007fe7fee1b6e4
ひとまず、対処策としては
① ロック呼び出しの原因となっているCUDA APIを特定し、そこの同時並列実行数に上限を加える。
② 当該事象は v3.x 系列では発生していない。CUDA Contextあたりのスレッド数が関係するのかも。
ひとまず、流石にワーカー数が増えた時にスレッド数が100を越えるのはやりすぎと反省。
スレッドを増やして同期APIを使うより、CUDAのAsync APIで代用する事を検討。
GPU Direct StorageのAync APIは12.0の時点ではまだ不安定であったので、まず12.3で検証。
ひとまず、567001445c41a63447d7a70a012ac7bd926cc94b
および 611889a43710d516eafa60bd5617a224a8a63bba
での修正でこちらはペンディング。
ToDoはNVIDIAのcuFileチームへのエスカレーション。
nvidia-fsのドライバ、普通にOSSになってるし、ポーリングの部分(ユーザ空間)を自前で実装すればよくないか。
これも v5.2 に向けて、根本原因の調査や対策を打ち込んでいく。
cuFileライブラリの中ではDevice Primary Contextを使っているので、実はCUDA Contextを自分で作るとCUDA Contextのスイッチングが頻繁に発生してしまう。
代わりに cuDevicePrimaryCtxRetain
を使うべき。