3

配列の要素に対していくつかの計算を行うアルゴリズムがあります。入力データバッファを再利用して結果を書き込みたいのですが。データトラバーサルパターンに関しては、ほぼ次のようになります(forループで発生する他の唯一のことは、いくつかのポインターへの増分と変数のカウントです)。

int *inputData = /*input data is here */;
for(int i=0;i<some_value;++i)
{
      int result = do_some_computations(*inputData);
      *inputData = result;
      ++inputData;
}

ここで興味深い部分:inputDataには約600万の要素が含まれています。inputData配列への書き込みをコメントアウトすると、アルゴリズムは基本的に次のようになります。

int *inputData = /*input data is here */;
for(int i=0;i<some_value;++i)
{
      int result = do_some_computations(*inputData);
     // *inputData = result;
      ++inputData;
}

このアルゴリズムは、一連の約100回の測定で、平均して約7ミリ秒かかります。ただし、書き込みをそのままにしておくと、アルゴリズムに約55ミリ秒かかります。「*inputData= do_some_computations(* inputData);」と書く 現在の方法ではなく、パフォーマンスに違いはありません。別のoutputBufferを使用しても違いはありません。

これは悪いです。このアルゴリズムのパフォーマンスは、プログラムの要件にとって絶対的に重要です。私は7ミリ秒で非常に満足していましたが、55ミリ秒で非常に不満です。

この単一の書き戻しがなぜこのような大きなオーバーヘッドを引き起こすのですか、そしてどうすればそれを修正できますか?

4

1 に答える 1

4

非ライトバックバージョンでは、コードは何も最適化されていません。これを示すために、5GHzのシングルコアCPUを想定すると、次のようになります。

7ms=35,000,000サイクル

600万アイテム=35/6=アイテムあたり5.8サイクル=多くの作業は行われていません

遅いバージョンの場合:-

55ms=275,000,000サイクル

600万アイテム=275/6=アイテムあたり45.8サイクル=アイテムあたりの作業量がはるかに多い

これを確認したい場合は、コンパイラからのアセンブリ出力を確認してください。

于 2013-01-11T11:19:37.703 に答える