8

独自の非インライン関数LockMutexとUnlockMutexがあり、これらは内部でブーストなどの適切なミューテックスを使用しているとします。LockMutexおよびUnlockMutexの呼び出しに関して、コンパイラーは他の操作を並べ替えないことをどのように知るのでしょうか。これらの関数を他のコンパイルユニットにどのように実装するかは、おそらくわかりません。

void SomeClass::store(int i)
{
  LockMutex(_m);
  _field = i;  // could the compiler move this around?
  UnlockMutex(_m);
}

ps:ロックを解除するために、クラスのインスタンスを使用してロックを保持することになっています。例を簡略化するために、これは省略しました。

4

6 に答える 6

3

これらの関数を他のコンパイル単位でどのように実装するかを知ることはできません。

これが重要です。コンパイラは関数呼び出しの実装について(一般的に)知ることができないため、ストアを_fieldそれらの関数呼び出しの外に移動することはできません。

通常、_field外部からアクセスできるSomeClass::store()(ローカルではない) ため、コンパイラは外部関数によって変更されているかどうかを知ることができないため_field、関数呼び出しシーケンス ポイント間へのストアを実行する必要があります。

基盤となるハードウェア プラットフォームでは、ハードウェアで発生するキャッシングまたは順不同の操作に対処するために、メモリ バリアまたはキャッシュ フラッシュの形で注意が必要になる場合があります。ミューテックス API のプラットフォームの実装は、必要に応じてこれらの問題に対処します。

于 2010-04-23T00:29:18.790 に答える
2

一般に、コンパイラは、実行時の動作に影響を与えないことが確実にわかっていない限り、コードを移動しません。

于 2010-04-22T22:49:16.560 に答える
1

書かれているように、関数がインラインでない場合、呼び出しが _field 変数とは無関係である可能性があるため、コンパイラは変数の割り当てを移動しませんが、呼び出しの厳密な順序を維持する必要があります。ただし、コンパイラが呼び出しをインライン化することを決定した場合、コンパイラーはそれらを独立したコードのブロックとして扱うと思います。つまり、同じコード単位 (インライン化された関数自体) 内の命令のみを並べ替えますが、前後の命令は並べ替えません。コード (_field 変数への代入)。

于 2010-04-22T22:57:41.703 に答える
1

おっしゃる通り、そのコードは正しく安全です。でも、「コード ジョーク」は思いつきました。

pthread_mutex_lock( &mx ) + foo() + pthread_mutex_unlock( &mx );
于 2010-04-22T22:58:21.400 に答える
0

コンパイラがそうしていた場合、それは悪いコンパイラになります。;-)

于 2010-04-22T22:44:26.047 に答える
0

関数呼び出しが呼び出し間で変数を変更する副作用を持たないことをコンパイラが保証できない場合、コンパイラはコードを移動できません。変数がローカル変数であり、参照を取得したり、その変数へのポインターを作成したりしたことがない場合、コンパイラーは移動しても安全であると想定する可能性があります。知らない。

于 2010-04-22T22:50:59.720 に答える