メモリへのアクセスに関連して、私は非常に奇妙なパフォーマンスの問題を抱えています。 コードスニペットは:なぜメモリアクセスが遅いのですか?
#include <vector>
using namespace std;
vector<int> arrx(M,-1);
vector< vector<int> > arr(N,arrx);
...
for(i=0;i<N;i++){
for(j=0;j<M;j++){
//>>>>>>>>>>>> Part 1 <<<<<<<<<<<<<<
// Simple arithmetic operations
int n1 = 1 + 2; // does not matter what (actually more complicated)
// Integer assignment, without access to array
int n2 = n1;
//>>>>>>>>>>>> Part 2 <<<<<<<<<<<<<<
// This turns out to be most expensive part
arr[i][j] = n1;
}
}
NとM - 10000ほど - 1000のオーダーの一部定数です。 このコード(リリース版)をコンパイルすると、パート2にコメントがあれば約15クロックかかる。この部分では、実行時間は100クロック以上になるので、ほぼ10倍遅くなります。私は割り当て操作が単純な算術操作よりもはるかに安価であることを期待していました。配列を使用しない場合、実際には真です。しかし、その配列では、割り当てははるかに高価なようです。 私は2-Dの代わりに1-D配列も試しました - 同じ結果(2Dの方が明らかに遅いです)。 また、ベクトル<の代わりにint **またはint *を使用しました。< int>>またはベクトル< int> - やはり同じ結果になります。
なぜ私は配列割り当てでこのようなパフォーマンスが低下するのですか?修正できますか?
編集: つ以上の観察:指定されたコードの一部2に、我々は(コメント内の数値)
n1 = arr[i][j]; // 16 clocks
速度に
arr[i][j] = n1; // 172 clocks
からの割り当てを変更する場合は上がります。私たちはラインを変更した場合さらに興味深いことに、:
arr[i][j] = n1; // 172 clocks
arr[i][j] = arr[i][j] * arr[i][j]; // 110 clocks
の速度も単純な代入 ためのより高いメモリへ/からの読み出しと書き込みのいずれかの違いはありますか?なぜ私はそのような奇妙なパフォーマンスを得ますか?
ありがとうございます!
これは単なる割り当てではありません。 – AJG85
ネストした 'vector'の代わりにフラットな配列を使うと、より良い結果が得られるかもしれません。 'boost :: multiarray'を試してください。 – pmr
であり、セルをメモリ順に処理したい場合があります。 – ysdx