OMP_PROC_BIND
現在の OpenMP 標準では、 OpenMP スレッドのバインドを制御するブール環境変数が定義されています。に設定した場合true
、たとえば
shell$ OMP_PROC_BIND=true OMP_NUM_THREADS=12 ./app.x
その場合、OpenMP 実行環境はプロセッサ間でスレッドを移動するべきではありません。残念ながら、これらのスレッドをどのようにバインドするかについては、これ以上何も述べられていません。これは、OpenMP 言語委員会の特別なワーキング グループが現在取り組んでいることです。OpenMP 4.0 には、スレッドの分散方法を指定できる新しい環境変数と句が付属しています。もちろん、多くの OpenMP 実装は、バインディングを制御する独自の非標準メソッドを提供しています。
それでも、ほとんどの OpenMP ランタイムは NUMA に対応していません。それらはスレッドを使用可能な CPU に喜んでディスパッチし、各スレッドがそのスレッドに属するデータのみにアクセスすることを確認する必要があります。この方向には、いくつかの一般的なヒントがあります。
dynamic
並列for
(C/C++) / DO
(Fortran) ループのスケジューリングを使用しないでください。
- 後で使用する同じスレッドでデータを初期化してみてください。
for
同じチーム サイズと同じ反復チャンク数で2 つの別々の並列ループを実行する場合static
、両方のループのチャンク 0 をスケジュールすると、スレッド 0 によって実行され、チャンク 1 - スレッド 1 によって実行されます。
- OpenMP タスクを使用する場合は、タスク本体のデータを初期化してみてください。これは、ほとんどの OpenMP ランタイムがタスク スチールを実装しているためです。アイドル スレッドが他のスレッドのタスク キューからタスクをスチールする可能性があります。
- NUMA 対応のメモリ アロケータを使用します。
私の同僚の何人かは、さまざまな OpenMP ランタイムの NUMA 動作を徹底的に評価し、特に Intel の実装の NUMA 認識を調査しましたが、記事はまだ公開されていないため、リンクを提供することはできません。
ForestGOMPと呼ばれる研究プロジェクトが 1 つあります。これは、NUMA 対応のドロップイン代替品を提供することを目的としていlibgomp
ます。見てみるといいかもしれません。