2011-12-20 17 views
0

整列サイズ配列と非整列サイズ配列で動作しようとしましたが、結果がパズルで、非整列サイズ配列は整列サイズのアレイよりも速く、これは私のコードである:整列サイズ配列と非整列サイズ配列で速度が異なる

TimeMeter timeMeter; 

const int N = 100000; 

_Tp A[64]; 
_Tp B[65]; 

int szA = sizeof(A); 
int szB = sizeof(B); 

// Method 1 
timeMeter.start(); 
for (int n = 0; n < N; n++) 
{ 
    memset(A, 0, szA); 
} 
timeMeter.stop(); 
printf("Method 1 Time usage = %f ms\n", timeMeter.span()); 

// Method 2 
timeMeter.start(); 
for (int n = 0; n < N; n++) 
{ 
    memset(B, 0, szB); 
} 
timeMeter.stop(); 
printf("Method 2 Time usage = %f ms\n", timeMeter.span()); 
  • _Tpchar(8)の場合:方法1つのコスト2.195msと方法2コスト2.175ms
  • _Tpintである(32)方法1コスト13.313ms、方法2コスト5.987ms
  • _Tpdouble(64)である:方法1つのコスト14.266msと方法2コスト11.304ms intがでなければならない自分自身だけ内で整列する必要がある、すなわちcharは1バイト境界で整列されている必要があり
+1

測定ごとにTimeMeterをリセットする必要がありますか? –

+0

@MitchWheat 'stop'とそれに続く' start'がおそらくそれをリセットします。 –

+0

@Seth:それは正常なAPIがすることです。 –

答えて

0

タイプ、 4バイトの境界に揃えられ、doubleは8バイトの境界に整列する必要があります。

は本当にやってみてください、不整列アクセスをテストするには

_Tp* A = (_Tp*)((char*)(new char[num * sizeof(_Tp)]) + 1); 

... 

delete[] (_Tp*)((char*)A - 1); 

さらに、これに関係なく、あなたはあなたができる配列で何をすべきか非整列されることはありませんchar秒、一連のポインタのようなmemset扱いのすべてアラインメントされていない書き込みを行うには、memsetを取得してください。

2

あなたのベンチマークは、いくつかの理由で無効です。

  1. 何もここでは、すべてのアライメントをチェックするために表示されません。あなたは単純に2つの異なるサイズの配列を持っています。 Plus memsetは、バイトレベルで動作するため、アライメントについてはあまり気にしません。
  2. ildjarnが指摘したように、このような少量のメモリ上のmemsetはあまり良くありません。それは単に速すぎますが、それ自体は大きな問題ではありません...
  3. ...あなたが設定しているメモリを使用していません。オプティマイザは、あなたのmemsetへの呼び出しを1つだけ残して、それを有効に排除できます。
  4. メモリを使用しないので、CPUは実際には特にループ間で多くの並べ替え/キャッシュを行っている可能性があります。
  5. ベンチマークの実行時間は、多くのOSでタイムスライスのサイズに近いものがあります(どれが1つなのかわからないので、多くのLinuxのように1msのタイムスライスを推測します)。これは、OSの切り替えのオーバーヘッドがテストの結果を大きく変える可能性があることを意味します。
  6. あなたの配列は相次いで割り当てられます。 CPUは順序を予測する傾向があるため、実際に結果に影響を与える可能性があります。あなたのループの順序を切り替えて、違いがあるかどうかを調べてみてください。
  7. 使用しているタイミングは指定していません。多くのタイマーはms精度テストに必要な解像度を持っていないため、結果に偏りが生じる可能性があります。
関連する問題