ひさびさにすっぽりとハマったのでメモ
OpenMPI 1.8.1な環境で、MPI/OpenMPのハイブリッド実行をしようとしてたのですが、
mpirun -np 1 ./a.out
とやるとOMP_NUM_THREADSの値に関わらず1coreしか使われないけど、mpirunを使わないで
./a.out
とすると、きっちりOMP_NUM_THREADSで指定したコア数まで使われるという謎の現象が起きてました。
結論を先に書くと、mpirunのオプション --bind-to を明示的に指定することでこの現象は解決します。
mpirun --bind-to board -np 1 ./a.out
みたいな感じで。
ちなみに、今回のテスト環境はシングルソケットのマシンだったのでboardを使ったけど、マルチソケットな環境であれば--bind-to socketを指定したうえで
プロセス数をsocket数(の倍数)にすることをお勧めします。*1
これはどういうことかというと、mpirun経由で実行した時は、デフォルト設定の"--bind-to core"の指定によって、生成されたプロセスとそこからfolkした子スレッド全てが同一コアに割り当てられてしまったために、何スレッド生成しようが1コアしか動かなかったんではないかと。
なんでこんなもんをデフォルトの挙動にしたのかと問い詰めたいとこですが、これやんないとflatMPIのプログラムをコアを余らせて実行した時に空いているコア間で
マイグレーションして、キャッシュミス頻発しちゃうという、嫌な状況になるので理解できなくはないです。
実際のところ、マイグレーションはされたくないけどどこのコアでも勝手に使ってくれて良いよというユーザの方が多いと思うので、デフォルトではpinning(一回使い始めたコアを使い続ける)は有効だけど、バインド(特定のRankを特定のコアに割り当てる)は無効になっているIntelMPIの方がありがたいなぁ。*2
OpenMPIの開発者の皆様には、夜中の1時にデバッガからomp_get_max_threads()した時の私の絶望を多少なりとも慮っていただきたいもんだ*3