6

私は最近、コンパイラが命令を再配置することでコードを最適化し、これはバリアを使用して制御できることを知りました。

IIRC では、ミューテックスをロックするとバリアが作成され、ミューテックスのロックを解除するとバリアが作成され、クリティカル セクション内のコードが外部に出ないようにします。

したがって、pthread_mutex_lock と pthread_mutex_unlock は暗黙的にこれらの「障壁」でなければなりません。ミューテックスをラップするこのようなクラスがある場合はどうなりますか?

class IMutex {
public:
    virtual void lock() = 0;
    virtual void unlock() = 0;
};

私には、コンパイラは、lock() 内で pthread_mutex_lock() を呼び出していること、および unlock() 内で pthread_mutex_unlock() を呼び出していることを認識しないようです。

これはバグにつながりますか?何らかの方法でバリアを手動で指定する必要がありますか?

4

1 に答える 1

6

命令の並べ替えは、さまざまなレベルで行われます。最も明白なものはコンパイラであり、あまり明白でないものは CPU (オンザフライ) です。ただし、同期関数はほとんどの場合フェンスであり、フェンスの前後の命令が並べ替えられるのを防ぎます。

したがって、仮想lock呼び出しのpthread_mutex_*()場合、仮想関数にはフェンスが含まれます。

したがって、短い答えは次のとおりです。いいえ、バグにつながることはありません。

volatile キーワードもあり、プラットフォームによってはフェンスを生成することもあります。ただし、揮発性キーワードを使用すると、揮発性の関数または変数を使用するたびにフェンスが導入されるため、これらのフェンスを検出することが非常に難しくなります。したがって、プラットフォームの同期機能を使用することをお勧めします。

フェンスに注意する必要があるのは、同時実行オブジェクトを使用して同期を実行していないときだけです (boolミューテックスの代わりに a を使用する場合など)。

于 2013-04-08T10:53:57.420 に答える