複数のプロセスによって並行して実行される次のコードを作成しました。
// spawn 10 times with id=0..9 by a master process.
void slave_processing(int id)
{
SHARED_TYPE last=id;
for(;;) {
/* each slave operates on a specific byte of the shared array. */
if (shared[id]!=last) fprintf(stderr,"S%i expected %i\n",id,last);
shared[id]+=id;
last+=id;
if (last>10*id) {last=0; shared[id]=0;}
}
}
それらはすべて同じ (IPC/linux) 共有メモリを使用していますが、それぞれが配列の個別のエントリにアクセスしています。と の両方の場合、デュアルコア マシンで問題なく動作しSHARED_TYPE
ます。アグレッシブな最適化 (-O3) でコンパイルし、アセンブルされたバイナリをチェックして、メモリ参照がアクセスに対して実行され、レジスタが使用されていることを確認しました。int
char
shared[id]
last
それでも、私は困惑しています。ある時点で、あるコアからのバイトへの影響が、他のコアからのキャッシュされたコンテンツに反映されない可能性があると予想していました。たとえば、あるコアがキャッシュに [xxyyzzuu] を持ち、[xxyyZZuu] をメモリに書き戻すと同時に、別のコアがメモリ ワードを [XXyyzzuu] にアップグレードした可能性があります (char の各ペアが 32 ビット ワードのバイトであると仮定します)。 .
shmget
で取得したメモリをキャッシュできないように、Linux は何らかの魔法の設定を行っていますか? または、コア #1 がコア #2 の最新の変更を読み取って、厄介な副作用なしで選択したバイトを更新できるようにする、低レベルのキャッシュ同期が行われていますか?
上記のコードが失敗した (fprintf に入った) 場所を知っている他の (マルチコア) アーキテクチャはありますか?