プライベート変数と共有変数は、広く使用されている事実上すべての OpenMP ランタイムで異なる方法で実装されています。
private
自動変数は実行中の各スレッドのスタックに存在し、threadprivate
変数は TLS に存在します。自動プライベート変数は、通常どおり登録するように最適化することもできます。
shared
並列領域の変数は通常、各スレッド関数への引数としてアドレスによって渡される構造体として実装され、その後、追加のポインター逆参照を使用して各共有変数にアクセスします。さらに、一部のコンパイラは共有変数を暗黙的に扱いvolatile
、ロード/更新/ストア命令の全スペクトルを発行しますが、OpenMP は、特定の同期まで、異なるスレッド内の共有変数の可視値間のある程度の不一致を許容する緩和されたメモリ モデルを提供します。そのようなポイントの 1 つは明示的なflush
ディレクティブです (依然としてflush
最も広く誤解されている OpenMP 機能であり、言語メーカーでさえ、標準ドキュメントでその使用法に関する例を入手できません)。
マルチスレッドの場合のヒープへのデータの割り当てに関しては、ほとんどのヒープ実装がリンクされたリストまたは同様のデータ構造を使用するため、ヒープ操作は本質的にシリアル化されます。また、通常のアロケータは、異なるスレッドによって割り当てられたデータがキャッシュ ラインを共有することになるかどうか、およびこれが誤った共有と関連するパフォーマンスの低下につながるかどうかを気にしません。hoard
、ptmalloc
、umem
、などの特殊なマルチスレッド アロケータがありtcmalloc
、より多くのメモリを使用してこれらの問題に対処しようとします。それらの一部 (例tcmalloc
) も NUMA 対応です。tcmalloc
ドキュメントは、STLコンテナがデフォルトのアロケータの代わりにそのアロケータを使用するようにするために何らかの「魔法」を行うと主張していますが、私は両方tcmalloc
とC ++のヘビーユーザーではないので同意できません。
NUMA システムで実行する場合に考慮すべきことの 1 つは、スレッド バインディングです。一部の OpenMP ランタイムには、コアへのスレッドのバインドを制御するための規定が既に含まれており、言語委員会で現在議論されているように、今後の OpenMP 標準には、バインディング プロパティを指定するための標準フレームワークが含まれる可能性が最も高いでしょう。