如何对齐std::数组中包含的数据
How to align std::array contained data?
由于std::array
不允许更改其分配器,是否有一种方法可以确保指向数据地址的指针对齐?
例如,在GNU g++ 4.8.4和6.1.0中,
下面的代码#include <array>
#include <iostream>
int main(void)
{
std::array<bool, 10> a;
std::array<char, 10> b;
std::array<int,10> c;
std::array<long long, 10> d;
std::array<float, 10> e;
std::array<double, 10> f;
std::cout << "array<bool,10>.data() = " << a.data() << std::endl;
std::cout << "array<char,10>.data() = " << (void*) b.data() << std::endl;
std::cout << "array<int,10>.data() = " << c.data() << std::endl;
std::cout << "array<long long, 10>.data() = " << d.data() << std::endl;
std::cout << "array<float, 10>.data() = " << e.data() << std::endl;
std::cout << "array<double, 10>.data() = " << f.data() << std::endl;
return 0;
}
提供了以下输出,显示在为x86-64位体系结构编译时,无论包含的数据类型如何,容器数据都对齐到16字节地址。
array<bool,10>.data() = 0x7ffe660a2e40
array<char,10>.data() = 0x7ffe660a2e30
array<int,10>.data() = 0x7ffe660a2e00
array<long long, 10>.data() = 0x7ffe660a2db0
array<float, 10>.data() = 0x7ffe660a2d80
array<double, 10>.data() = 0x7ffe660a2d30
然而,对于Intel的icpc v16.0.3,即使使用-align
,结果也如下所示。虽然大多数容器都对齐到16字节地址,但有些容器(char
和float
数组)对齐到较小的字节地址(分别为2字节和8字节)。
array<bool,10>.data() = 0x7ffdedcb6bf0
array<char,10>.data() = 0x7ffdedcb6bfa
array<int,10>.data() = 0x7ffdedcb6ba0
array<long long, 10>.data() = 0x7ffdedcb6b00
array<float, 10>.data() = 0x7ffdedcb6bc8
array<double, 10>.data() = 0x7ffdedcb6b50
编辑
只是为了举例说明来自RustyX的提议,这是修改后的代码
#include <array>
#include <iostream>
int main(void)
{
alignas(16) std::array<bool, 10> a;
alignas(16) std::array<char, 10> b;
alignas(16) std::array<int,10> c;
alignas(16) std::array<long long, 10> d;
alignas(16) std::array<float, 10> e;
alignas(16) std::array<double, 10> f;
std::cout << "array<bool,10>.data() = " << a.data() << std::endl;
std::cout << "array<char,10>.data() = " << (void*) b.data() << std::endl;
std::cout << "array<int,10>.data() = " << c.data() << std::endl;
std::cout << "array<long long, 10>.data() = " << d.data() << std::endl;
std::cout << "array<float, 10>.data() = " << e.data() << std::endl;
std::cout << "array<double, 10>.data() = " << f.data() << std::endl;
return 0;
}
,这是在英特尔的icpc v16.0.3中编译它的结果。
array<bool,10>.data() = 0x7ffe42433500
array<char,10>.data() = 0x7ffe42433510
array<int,10>.data() = 0x7ffe424334a0
array<long long, 10>.data() = 0x7ffe42433400
array<float, 10>.data() = 0x7ffe424334d0
array<double, 10>.data() = 0x7ffe42433450
默认情况下,当涉及到对齐时,编译器会做正确的事情。
但是你可以用alignas
:
alignas(16) std::array<char, 10> b;
附启
有趣的是,Intel编译器认为在8字节上对齐char[]
就足够了。就好像它知道在x86平台上把它对齐得再宽也不会有什么好处。
请记住,过多的对齐会降低性能,因为这会增加内存使用和降低缓存效率。现代x86架构(Sandy Bridge和更新版本)在处理未对齐的数据时非常有效,但无法补偿部分使用的缓存线(更多信息)。
相关文章:
- C++:__aligned(__alignof__) 导致字符数组数据出现问题?
- 很好的语法来获取对向量/数组数据的大小引用?
- 数组数据以错误的方式遍历 Python/Matlab
- 访问 Arduino 中的结构数组数据
- 在能够从 Web 浏览器访问大型数组数据的同时存储它的最可行方法是什么?
- 在C 类中声明数组数据
- 如何在 c++ 中将字符串数组数据写入输出文件
- 使用 stl::map 和 stl::unordered_map 对包含大量重复元素的数组数据进行排序
- 检索字符数组数据时出现问题
- 共享库的C 访问数组数据
- 将包含数组数据成员的结构保存到文件
- C++中的LinkedList字符数组数据
- 正在尝试使用if语句检查数组数据
- 在单独的数据中显示数组数据
- 如何在 c++ 中将字节类型的字符数组数据保存到文件中
- 从数组数据中缺少第一个元素的 DLL 返回C++结构
- 如何在C++中表示二进制字节数组数据
- 实现动态数组数据结构时出现"double free or corruption"错误
- 多维数组数据成员的运行时错误
- C++ :使用 * 显示数组数据的条形图