2016-10-11 10 views
0

ローカル変数(intなど)は、少なくともそのアドレスがどこにも必要でない限り、プロセッサレジスタに格納することができます。たとえば、複雑なハッシュを計算する関数を考えてみましょう。メンバー変数(属性)はC++のレジスタに存在できますか?

ここで、バッファはメモリに収まらないとします。我々はfoo複数回呼び出し、データのチャンクからハッシュを計算するためのクラスを記述:

struct A 
{ 
    void foo(int const* buffer, int size) 
    { 
     // perform heavy computations involving frequent reads and writes to a 
    } 

    int a; 
}; 

A object; 
while (...more data...) 
{ 
    A.foo(buffer, size); 
} 
// do something with object.a 

例では、ビット不自然であってもよいです。ここでの重要な違いは、aがフリー関数のローカル変数であり、オブジェクトのメンバー変数であるため、状態が複数の呼び出しで保持されることです。

今質問:fooメソッドの冒頭にaメソッドをレジスタにロードして最後に格納するのは合法でしょうか?実際には、これはオブジェクトを監視する第2のスレッドが中間値a(同期と未定義の動作を脇に)を決して観察できないことを意味する。スピードがC++の主要な設計目標であるならば、これは合理的な動作であるようです。コンパイラーがこれをやるのを防ぐ標準が何かありますか?いいえの場合、コンパイラは実際にこれを行いますか?言い換えれば、メンバ変数を使用した場合、機能の始めと終わりに一度ロードして保存する以外に、(おそらく小さな)パフォーマンスペナルティを期待できますか?

私が知る限り、C++言語自体はレジスタが何であるかを指定していません。しかし、とにかく問題ははっきりしていると思います。これは重要なことですが、私は標準的なx86またはx64アーキテクチャの答えに感謝します。

+0

"register"と "volatile"フラグを確認してください – amchacon

+0

@amchacon実際、C++には現在 'register'キーワードがあります。しかし、私は、C++では非推奨であることをさらに指摘しています。 –

答えて

2

fooの実行中にaにアクセスすることは他に何もないことが証明できる場合、コンパイラはこれを行うことができます。
これは一般的な問題ではありません。私はそれを解決しようとするコンパイラはないと思います。

struct B 
{ 
    B (int& y) : x(y) {} 
    void bar() { x = 23; } 
    int& x; 
}; 

struct A 
{ 
    int a; 
    void foo(B& b) 
    { 
     a = 12; 
     b.bar();    
    } 
}; 

(もっと不自然)の例を考えてみましょう十分に無実に見えますが、その後、私たちは、これが23baz.a12をないままになり、それが "最適化"

A baz; 
B b(baz.a); 
baz.foo(b); 

を言います明らかに間違っている。

+0

この例では、マルチスレッドはなく、オブジェクトはローカルに作成されるため、コンパイラはどのようにプリミティブを証明していないのですか?マルチスレッドの場合でも、変数をレジスタに保持することは、実際にはロックされていない状態でアクセスするときに問題になります(実際の問​​題はロックされません)。 – stefaanv

+0

私は、関数がインライン化できるならば、それを証明する良い機会があると認めます。 – stefaanv

+0

ありがとうございます。私はループ中に一時的に登録しておくことを考えていましたが、コンパイラが証明できるものには限界があります。特に関数との組み合わせでは限界がありますが、プリミティブにも参照があることを忘れないでください。 – stefaanv

1

「メンバー変数(属性)はレジスタに存在できますか?」への簡単な答え:はい。

一時的な結果をレジスタに保存することは、バッファを反復して一時的な結果をプリミティブのいずれかの種類に書き込むときに、どこに置いてもよい最適化になります。これはコンパイラで頻繁に行われます。しかし、それは実装ベースであり、渡されたフラグの影響を受けているので、結果を知るには、生成されたアセンブリをチェックする必要があります。

+0

素早い答えをありがとう。それが私が期待していたものであり、実際に望んでいたことですが、私の懸念事項が無効であることを知っていることは良いことです。 – tglas

関連する問題