2010-11-24 4 views
3

コンテキスト:C++:(アライメントを学ぼう)char配列の異なる場所を指し示すポインタの比較パフォーマンス

char buffer[99]; int* ptr_int=(int*)(buffer+n); 

その後、私は窓を使用して*のptr_intと対策の実行時にいくつかの時間操作を消費しません.h/QueryPerformanceCounter。

混乱:Nの値に対して :0~4、実行時間は、nの値は約12秒である :32,33:5,6,7実行時間は、nの値は約20秒である 実行時間は約12秒です。

これは調整のためかもしれませんが、どのように正確に説明できますか?

ペンティアムデュアルコアT2410/winxpと/グラム++ 3.4.2(mingwの特殊)

編集 私の代わりに私がしようとしています、より良いアプローチを使用することにより、アライメント問題を回避しようとしているわけではありません現代のCPU上int* ptr_int=(int*)(buffer+3); OR int* ptr_int=(int*)(buffer+33);

+0

これは一部のアーキテクチャでは動作しません。ハードウェア障害が発生します。あなたはあなたのコンパイラが補償しているか、あなたのハードウェアがそれでOKであることを幸運に思っているようです。アラインメントは、オブジェクトのサイズに対して行う必要があります。 –

+0

配列の問題を排除する場合は、配列のchar要素にアクセスする時間を測定するか、int配列を使用してください。 – Amnon

+0

また、 'buffer'のアドレスを見て、どのように整列しているかを確認してください。 – antsyawn

答えて

1

、データは他の適切に配置する必要がある、または:私は突然とint* ptr_int=(int*)(buffer+5);

ない問題との整合の問題を抱えている理由を見つけるために地獄があります。 32ビット整数は4バイトで整列する必要があります。そうでなければ、CPUは内部的に2つの整数を読み込み、物事を適切に近づける必要があります。いくつかのCPUは、整列していない整数を読み取ろうとすると実際にクラッシュします。同様に

、16バイトで整列する必要が__vector4 128ビット、ところでなど

、データ・キャッシュ・ラインのように、遊びに来て、他の要因があるので、初めてあなたのアクセス新しいキャッシュライン、大きなペナルティがあります - その後の読み取りははるかに高速になります。

0

Ulrich Drepperの優れた論文「What Every Programmer Should Know About Memory」は、この問題やその他のメモリ問題の完全な説明と、自分で実行できるベンチマークの例を参照してください。

0

他の人と同じように、これはアラインメントの問題だと言います。今あなたがそれを修正し、それをテストできるいくつかの方法があります。

mallocまたはnewを使用して、ヒープにバッファを割り当てるのが最も簡単です。 Mallocは返されたポインタが最大のネイティブデータ型の配置に適していることを保証します。 Intel 64ビットチップでは、128ビットの倍精度にアライメントされます。

char * buffer = malloc(n * sizeof(int)); 

int * at = (int*)buffer + ndx; 

+nも間違っていたように見えます。あなたがしたやり方は、char ptrをint ptrではなく1バイトだけ4バイトオフセットすることでした。これは、整数をコピーしている場合の減速を説明することもできます。これは、誤って同じメモリ位置に重なる整数を使用している可能性があるためです。

スタック割り当てを使用しなければならない場合は、スタック割り当てを行うこともできます。ブーストこれを行う機能を、私は信じているだけでなく

char cbuffer[1024+sizeof(int)]; 
int * ibuffer = (cbuffer/sizeof(int) + 1) * sizeof(int); 

その後ibufferが整数整列されますがあります。実際のポインタの値はcbufferと同じではない場合もありますが、(呼び出し時のスタックによって異なります)場合もあります。 2行目はポインタの単純な数学で、sizeof(int)の倍数であることを保証します。つまり、intに整列しています。

new:new char[x]でもアライメントが保証されているかどうかを誰かが確認できますか?malloc

関連する問題