デッカーのアルゴリズムは、マルチコアプロセッサで失敗します

オリジナルリンク: http://www.cnblogs.com/lijingcheng/p/4454868.html

デッカーアルゴリズムは 2つのスレッドが同時に一貫性の順に追従する限り、CPU・メモリ・モデルであるとして(クリティカルセクションに入ることができないように、周知の並行プログラミングアルゴリズムである、デッカーアルゴリズムの核心は、共有変数のセットにアクセスするために対称的なコードのセットでありますa)は、スレッドの同期を達成するように。以下は、アルゴリズムの実装です。

静的な 揮発性の int型 FLAG1 = 0 ;
静的な 揮発性の int型の FLAG2 = 0 ;
静的な 揮発性の int型のターン= 1 ;
静的な 揮発性の int型 gSharedCounter = 0 ; 

ボイドdekker1(){ 
FLAG1 = 1 
ターン = 2 ;
一方、((FLAG2の== 1)&&(==オン2 ))。
// クリティカルセクション 
gSharedCounter ++ ;
// 他のタスクの実行をしてみましょう
FLAG1 = 0 ; 
} 

ボイド dekker2(ボイド){ 
FLAG2 = 1 
ターン = 1 ;
一方、((FLAG1の== 1)&&(==オン1 ))。
// クリティカルセクション 
gSharedCounter ++ ;
// ままクリティカルセクション 
FLAG2 = 0 ; 
}

実現への鍵((FLAG 2 == 1)&&(== 2を回す))と((FLAG1 == 1)&&()== 1を回しては)排他的アクセスを可能にし、同時に確立することはできませんしばらくながら、その重要なエリア、そして条件が同時に確立することができないので、それがデッドロックにつながることはありません。私たちは、次の例で試験しました。

int型gLoopCount;
無効 * TASK1(ボイド *の引数){
 int型私は、
printf(" 開始task1n " );
以下のための(I = gLoopCount; I> 0 ; i-- ){ 
dekker1()。
} 
} 
ボイド *のタスク2(ボイド *の引数){
 int型のI。
printf(" 開始task2n " );
以下のための(I = gLoopCount; I> 0 ; i-- ){ 
dekker2()。
} 
}

シングルコアプロセッサでは、マルチスレッドの方法が実行されている回数に関係なく、コードを実行しないように、プログラムが間違って行くことはありません。シングルコアCPUのメモリモデルは、一貫性(シーケンシャル一貫性)の順序に従うことであるためである、逐次一貫モデル(後にSCと呼ばれる)、それはプログラムがマルチスレッドの実行順序を持っているべきであると私たちの印象があるという単純な事実。正確な順序(プログラム順)で完全に不必要なCPU /コンパイラは、各命令を実行するためのコードで指定されているためしかし、最大の問題のSCが低すぎるパフォーマンスは、あります。学びアーキテクチャの学生は、彼らがベストを尽くす何をするご注文の最適化の外に行う手助けで、コンパイラのCPUイェジンハオかどうかを知っている必要があります。彼らはプログラムの実行結果は、あなたと一緒に最適化されていることを確認しますので、障害シリアル最適化の時代では、プログラマ、良いパッケージに透明であり、あなたは、彼らが順不同であなたにChengshayangを与え、最終的には気にしませんプログラムは、結果はまったく同じです書くことが期待されています。しかし、マルチコア時代に入った後に、CPUとコンパイラの最適化は、これらのシリアル時代は、もっと重要なのは、これらの最適化は、SCモデルのセマンティクスをあなたのマルチスレッド・プログラムを中断しますやるし続けるように私たちのマルチスレッド・プログラムの実際の業績異なることが予想営業成績!
X86を取り、弱い順序付けの一部であり、厳密にSCを強制することはありませんそのマルチプロセッサのメモリモデル、(またはと呼ばれるには、順序をリラックス?)。ロードがストアに言及異なるアドレス上で動作することができる前に-それだけ(>店舗Xを、すなわち、店舗X->負荷yはYをロードするために最適化されたスクランブル)の順序の最適化の出入りさせることができます。そして店舗X - >店舗Y、負荷 X - >負荷のY、 及び負荷Y - >交換の店舗X実行順序が許可されていません。
どのような順序がFLAG1とFLAG2を更新するので、したがって、マシンの弱いメモリ一貫性を保つため、アルゴリズムは、失敗する可能性があるため制限されていない、特に、FLAG2を保証することはできませんdekker2にdekker1で発生する操作を読みます書き込み動作後FLAG1を回します。
dekkersbug.png

参考:マルチコア、マルチスレッドのプログラムは、注意volatileキーワードを使用しなければならない理由の分析?

ます。https://www.cnblogs.com/lijingcheng/p/4454868.htmlで再現

おすすめ

転載: blog.csdn.net/weixin_30764883/article/details/94783179