Mat*_*hai 3 c c++ memory-management
我的理解是,如果您希望数组对齐,则必须明确指定数组的对齐方式。
但是,我声明的浮点数组似乎总是与 16 字节对齐。
float *ptr1 = new float[1];
cout<<"ptr1: "<<ptr1<<endl;
float *ptr2 = new float[3];
cout<<"ptr2: "<<ptr2<<endl;
float arr1[7];
cout<<"arr1: "<<arr1<<endl;
float arr2[9] __attribute__((aligned(2)));
cout<<"arr2: "<<arr2<<endl;
Run Code Online (Sandbox Code Playgroud)
这是输出
ptr1: 0x13dc010
ptr2: 0x13dc030
arr1: 0x7fff874885c0
arr2: 0x7fff87488590
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?我正在使用 gcc 4.6.3
但是,如果它是指向浮点位置或静态分配的指针,则我看不到它
static float arr3[9] __attribute__((aligned(2)));
cout<<"arr3: "<<arr3<<endl;
float *x;
cout<<"x: "<<x<<endl;
Run Code Online (Sandbox Code Playgroud)
输出:
arr3: 0x4030b2
x: 0x7fff8c7dd9e8
Run Code Online (Sandbox Code Playgroud)
此代码在 x64 上运行。
对齐要求由每个编译器确定,受硬件要求和任何相关ABI 的影响。
C 和 C++ 语言讨论了类型的对齐,但它们没有强加任何特定要求(例如,结构的对齐至少是其任何成员的对齐除外)。一个有效的实现可以允许所有数据类型按字节对齐,或者它可以要求每个标量类型与其自己的大小对齐(后者更常见)。中间对齐是可能的,例如在 4 字节边界上对齐 8 字节类型。
特别是在 x86 上,将标量与其大小对齐可以提高访问效率,但未对齐的访问仍然可以正常工作,尽管速度会慢一些。
在需要对的阵列对准float是相同的单个所需的对准float对象。如果float是 4 个字节,则该对齐不能超过 4 个字节,因为数组的元素之间没有间隙。
一个特定的编译器可能会选择对数组对象施加更严格的对齐,正如您(可能)所看到的,如果它使访问这些对象的效率更高一些。
如果new操作符是通过调用实现的malloc,那么所有new分配的对象都将具有对任何类型都足够严格的对齐方式。
如果float数组始终与 16 字节边界对齐,那是因为您的编译器选择以这种方式分配它们,而不是因为语言需要这样做。另一方面,如果您使用别名将float数组强制为4 字节对齐(假设sizeof (float) == 4),则对该数组及其元素的访问仍应正常工作。
顺便说一句,当我main在 x86_64 系统上运行您的代码(将其封装在程序中之后)时,我得到与您类似的结果。当我在 x86 系统上运行它时,我得到:
ptr1: 0x9e34008
ptr2: 0x9e34018
arr1: 0xbfefa160
arr2: 0xbfefa17c
Run Code Online (Sandbox Code Playgroud)
我在两个系统上都在 Linux 下使用 gcc。
因此,您问题的直接答案是否定的,float数组并不总是与 16 字节边界对齐。
但在大多数情况下,您没有特别的理由需要关心。除非您使用别名技巧(将某个声明类型的对象视为另一种类型的对象),否则编译器将始终至少为每个对象提供正确访问所需的对齐方式。
| 归档时间: |
|
| 查看次数: |
2413 次 |
| 最近记录: |