如何对齐std :: array包含的数据? [英] How to align std::array contained data?

查看:102
本文介绍了如何对齐std :: array包含的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于std::array不允许更改其分配器,有没有办法确保指向数据地址的指针对齐?

Since std::array does not allow changing its allocator, is there a way to ensure that the pointer to the data address is aligned?

例如,在GNU g ++ 4.8.4和6.1.0中,下面的代码

For instance, in GNU g++ 4.8.4 and 6.1.0, the code below

#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;
}

提供以下输出,该输出显示容器数据针对16字节地址对齐,而不考虑针对x86-64位体系结构进行编译时所包含的数据类型.

provides the following output that shows that the container data is aligned to 16-byte addresses no matter the data-type contained when compiling for an x86-64 bit architecture.

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字节地址,但某些容器(charfloat数组)却对准了较小的字节地址(分别为2字节和8字节).

However, for Intel's icpc v16.0.3 the result is shown below even using -align. While most of containers are aligned to 16-byte addresses, some (char and float arrays) are aligned to smaller byte addresses (2-byte and 8-byte, respectively).

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为例,这是更改后的代码

Just to exemplify the proposal from RustyX, this is the changed code

#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进行编译时的结果.

and this is the result when compiling it with Intel's 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

推荐答案

默认情况下,编译器在对齐时会做正确的事情.

By default the compiler will do the right thing when it comes to alignment.

但是您可以使用alignas覆盖它:

But you can override it with alignas:

alignas(16) std::array<char, 10> b;


后记

有趣的是,英特尔编译器认为将char[]对齐到8个字节就足够了.好像知道一样,在x86平台上通过将其更宽地对齐几乎不会得到什么收益.


Postscriptum

It is interesting that the Intel compiler thinks it is sufficient to align a char[] on 8 bytes. It is as if it knows that on an x86 platform you gain little by aligning it any wider.

请记住,由于增加了内存使用量并降低了缓存效率,过多的对齐会降低性能.现代x86架构(Sandy Bridge和更高版本)可以非常有效地处理未对齐的数据,但无法补偿部分使用的缓存行(

Keep in mind that too much alignment can reduce performance due to increased memory use and reduced cache efficiency. Modern x86 architectures (Sandy Bridge and newer) work very efficiently with unaligned data, but cannot compensate for partially used cache lines (more info).

这篇关于如何对齐std :: array包含的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆