Sun Studio 12: OpenMP API ユーザーズガイド

6.2 「偽りの共有」とその回避方法

OpenMP アプリケーションで不注意に共有メモリー構造体を使用すると、パフォーマンスおよびスケーラビリティーが低下することがあります。メモリー上の連続する共有データを複数のプロセッサが更新すると、マルチプロセッサインターコネクタに過度のトラフィックが生じ、結果的に計算の直列化の原因になることがあります。

6.2.1 「偽りの共有」とは

UltraSPARC プロセッサなどの大部分の高性能プロセッサでは、低速のメモリーと CPU の高速レジスタの間にキャッシュバッファーが 1 つ挿入されています。メモリー上の場所にアクセスすると、その要求された場所を含む実際のメモリーのスライス (キャッシュライン) がキャッシュにコピーされます。同じメモリー上の場所またはその周囲の場所への以降の参照は、多くの場合、キャッシュとメモリー間の整合性を維持する必要があるとシステムが判断するまで、キャッシュから満たすことができます。

ただし、同じキャッシュライン内の個々の要素に対する、異なるプロセッサからの同時更新があると、それらの更新が互いに論理的に独立していても、キャッシュライン全体の妥当性が失われます。このため、キャッシュラインの個別要素の更新があると、その都度、そのラインには「無効」のマークが付けられます。同じキャッシュライン上の別の要素にアクセスするほかのプロセッサは、そのラインに「無効」のマークが付いていることを検出します。このため、そのプロセッサは、アクセスしようとする要素が変更されていなくても、メモリーなどの場所からそのラインの最新のコピーをフェッチすることになります。これは、キャッシュ整合性をキャッシュラインのレベルで維持するためであり、個別の要素のためではありません。この結果、インターコネクトのトラフィックとオーバーヘッドが増加することになります。また、キャッシュラインが更新中、そのライン上の要素へのアクセスは禁止されます。

この状態は「偽りの共有」と呼ばれます。頻繁にこの状態になる場合は、OpenMP アプリケーションのパフォーマンスとスケーラビリティーが大幅に低下します。

偽りの共有によってパフォーマンスが低下するのは、次の条件のすべてが満たされる場合です。

ループ内で読み取り専用の共有データは偽りの共有にはならないことに注意してください。

6.2.2 偽りの共有の低減

アプリケーションの実行で主要な役割を果たす並列ループを綿密に分析することによって、偽りの共有によって引き起こされるパフォーマンスおよびスケーラビリティー上の問題を明らかにすることができます。一般に、偽りの共有は次のことを行うことによって減らすことができます。

場合によっては、大きなサイズの問題を処理しているときは共有が少ないために、偽りの共有の影響がわかりにくいことがあります。

偽りの共有を追跡するための技法は、アプリケーションによって大きく異なります。データの割り当て方法を変更すると、偽りの共有が減少する場合があります。スレッドの反復のマッピングを変更し、チャンクごとの各スレッドの作業量を増やす (chunksize 変数を変更する) ことでも、偽りの共有が減少することもあります。