2

今回は、探しているものが見つかりませんでした (適切なものを探していない場合はわかりません...) が、ここにあります:

C ++で、Bar()サイクルごとに1回呼び出される関数があると想像してください...次のように:

class Foo {
 public:
   void Bar() {
     double my_array[3]; 
     // fills the array based on some calculations
     double my_array1[3]; 
     // fills the array based on some calculations
     double my_array2[3];
     // fills the array based on some calculations
     _member_of_class = my_array + my_array1 + my_array2; //+ overloaded
   }

 private:
   float _member_of_class[3];
}

int main(int argc, char** argv) {
  Foo foo;
  while(/*program running*/) {
    foo.Bar();
    //LOTS of code here
  }
  return 0;
}

さて、my_arrays は一時的な配列であり、データ メンバーであることは重要ではなく、クラス メンバーを埋めるために使用されるだけです...明らかに、その関数を呼び出すオーバーヘッドは必要ありません...方法はありますか (まあ、私はしようとしています)それらをクラスメンバーとして配置することは避けてください)、コンパイラーに「割り当てスペースを節約する」または何かを指示して、オーバーヘッドが少なくなるようにしますか? const はコンパイラに何かヒントを与えるでしょうか? 私ははっきりしているのかどうかわかりません...

とりあえずありがとう!

4

4 に答える 4

3

プロファイラーを使用する

現状では、関数はクラス内でインラインで宣言されています。このコードは自明に最適化され、コンパイラはおそらくループから割り当てを取得します (実際には、画像からどれだけ残しているかによって異なります)。

また、オーバーロードされた配列演算子は gcc でベクトル化される可能性があります (-ftree-vectorize の -O3 で始まります)。冗長出力を見てください

g++ -O3 -march-native -ftreevectorizer-verbose=2 ...

どのループがベクトル化されたかを確認し、そうでない場合はその理由を確認します。g++ -S などの出力をぜひご覧ください。

プロファイラーを使用します。最適化が必要かどうかわからない場合は、「最適化」しないでください。

于 2011-05-07T23:31:43.960 に答える
0

アレイをプライベートメンバーにすることを検討してみませんか?実行時にスタック割り当てのオーバーヘッドがないことを保証したい場合は、それらをプライベートメンバーにすることで、他のプログラマーにそれが起こっていることを明確にします。コンパイラーの切り替えや、コンパイラーによって自動的に行われる最適化への依存は、他のプログラマーにとって必ずしも明白ではありません。開発者

于 2011-05-08T00:24:16.197 に答える
0

配列を静的として宣言できます。これにより、コンパイラは、関数を呼び出すたびにメモリをスタックに置くのではなく、メモリを予約するように強制されます。ただし、これはスレッドセーフに違反することに注意してください。

また、スタックは事前に割り当てられていることに注意してください。このコードは、実際には配列に新しいメモリを割り当てていません。既に割り当てられているメモリにそれらを配置しているだけです。ここにはオーバーヘッドはありません。コンパイラは、1 つの命令だけで 3 つの配列すべてにスペースを確保できます。

于 2011-05-07T23:22:51.903 に答える
0

それらをパラメーターとして Bar 関数に渡します。配列はポインターに分解され、渡すのが非常に高速になります。

于 2011-05-07T23:23:31.717 に答える