23

また、glibc malloc() がこれを行うかどうかも知りたいです。

4

4 に答える 4

77

あなたが構造を持っていると仮定します。

struct S {
    short a;
    int b;
    char c, d;
};

アラインメントがないと、次のようにメモリに配置されます(32ビットアーキテクチャを想定)。

 0 1 2 3 4 5 6 7
|a|a|b|b|b|b|c|d|  bytes
|       |       |  words

問題は、一部のCPUアーキテクチャでは、メモリから4バイト整数をロードする命令がワード境界でのみ機能することです。したがって、プログラムはb別々の命令でそれぞれの半分をフェッチする必要があります。

しかし、メモリが次のようにレイアウトされている場合:

 0 1 2 3 4 5 6 7 8 9 A B
|a|a| | |b|b|b|b|c|d| | |
|       |       |       |

そうすれば、へのアクセスbが簡単になります。(欠点は、パディングバイトのためにより多くのメモリが必要になることです。)

データ型が異なれば、アライメント要件も異なります。char1バイトにアラインされ、short2バイトにアラインされ、4バイトタイプ(int、、、floatおよび32ビットシステムのポインタ)が4バイトにアラインされるのが一般的です。

mallocC標準では、任意のデータ型に適切に配置されたポインタを返す必要があります。

x86-64上のglibcmallocは、16バイトに整列されたポインターを返します。

于 2010-10-22T05:45:09.473 に答える
10

アライメント要件は、どのタイプにどのアドレス オフセットを割り当てることができるかを指定します。これは完全に実装に依存しますが、通常はワード サイズに基づいています。たとえば、一部の 32 ビット アーキテクチャでは、すべてのint変数が 4 の倍数で始まる必要があります。一部のアーキテクチャでは、配置要件が絶対的です。他のもの (x86 など) では、それらを無視すると、パフォーマンスが低下するだけです。

mallocアライメント要件に適したアドレスを返す必要があります。つまり、返されたアドレスは、任意の型のポインターに割り当てることができます。C99 §7.20.3 (メモリ管理機能) から:

割り当てが成功した場合に返されるポインターは、任意の型のオブジェクトへのポインターに割り当てられ、割り当てられた空間内のそのようなオブジェクトまたはそのようなオブジェクトの配列にアクセスするために使用されるように適切に整列されます (空間が明示的に割り当て解除されるまで)。 .

于 2010-10-22T05:08:19.640 に答える
1

(特定のハードウェアまたはライブラリに対して) 特定のメモリ アライメントが必要な場合は、_aligned_malloc()やなどの移植性のないメモリ アロケータを確認できますmemalign()。これらは「移植可能な」インターフェースの背後で簡単に抽象化できますが、残念ながら非標準です。

于 2010-10-22T05:17:25.810 に答える
0

malloc()ドキュメントには次のように記載されています。

[...] the allocated memory that is suitably aligned for any kind of variable.

これは、C/C++ で行うほとんどすべてに当てはまります。ただし、他の人が指摘したように、多くの特殊なケースが存在し、特定の調整が必要です。たとえば、Intel プロセッサは 256 ビット タイプをサポートして__m256いますmalloc()

同様に、ページングされるデータにメモリ バッファを割り当てたい場合 (mmap()などによって返されるアドレスと同様)、非常に大きなアラインメントが必要になる可能性があり、malloc()常にアラインされたバッファを返す場合、多くのメモリを浪費することになります。そのような境界。

Linux またはその他の Unix システムでは、次のposix_memalign()関数を使用することをお勧めします。

int posix_memalign(void **memptr, size_t alignment, size_t size);

これは、そのようなニーズに使用したい最新の機能です。

于 2012-12-26T09:23:28.267 に答える