c++ - 如果 T 对齐, std::vector<T> 也对齐吗?

标签 c++ caching c++11 vector memory-alignment

我正在浏览一些新的 C++14 功能和 aligned_storage引起了我的注意,在讨论了并发性、局部性和数据结构对齐之后,我想到了分配给 std::vector 的内存块这一事实。保证在内存中是连续的,但这并不一定意味着 vector 本身被有效打包,或者更好地说,您关心的数据被有效对齐,关于该数据的信息可能有额外的东西结构不一定对计算有用,并且可能会干扰您的数据。

所以我问,我是否有 class T我知道T按照我喜欢的方式对齐和包装,std::vector<T>也会对缓存友好并在管道中对齐吗?

我的问题涵盖 C++11 和 C++14,仅涉及数据结构布局,我没有考虑与缓存行组织相关的其他问题(例如错误共享)或与事物如何获取相关的其他问题获取、加载并执行。

我知道这听起来很愚蠢,但这只是我的疑问。

最佳答案

C++ 默认分配器需要为任何所谓的标准类型正确对齐结构,并且在结构末尾自动添加的填充(通过 sizeof() 可见)通常有助于在连续分配中实现这一点。

struct C {
  uint8_t  a; // followed by 7B of invisible padding to naturally align b
  uint64_t b;
  uint32_t c;
  uint8_t  d; // followed by 3B padding for C (natural alignment of 8B due to b)
};
// sizeof(C) = 24B, alignof(C) = 8B

struct D {
  uint8_t  a; // followed by 3B padding for b
  uint32_t b;
  uint8_t  c; // followed by 3B padding for D (natural alignment of 4B due to b)
};
// sizeof(D) = 12B, alignof(D) = 4B

struct E {
  __m256 v; // SSE/AVX intrinsics handle natural alignment properly too
  char v2;
};
// sizeof(E) = 64B, alignof(E) = 32B

对于大多数情况,这已经足够了,但是如果您正在执行花哨的转换技巧或需要 64B 缓存行对齐等,则可以使用 alignas() ,前提是您使用的是 C++11 或更高版本。这也部分通过填充结构的末尾来实现:

struct alignas(64) F {
  double stuff[3];
};
// sizeof(F) = 64B, alignof(F) = 64B

void foo() {
  F f[4];
  // these addresses separated by (and even multiples of) 0x40 bytes:
  cout << &f[0] << " " << &f[1] << " " << &f[2] << endl;
}

使用std::aligned_storage<T>如果您需要与例如 4 kiB 页边界对齐的大块。但接下来你就只能靠自己来定位 new总的来说又失去了std::vector<>的便利性为你做一切。

关于c++ - 如果 T 对齐, std::vector<T> 也对齐吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23713651/

相关文章:

c - 用于缓存模拟器的 Malloc 两个结构

c++ - 如何实现 "const"和 "non-const"重载而不重复代码?

c++ - 可变参数模板,获取函数参数值

c++ - 查询事件日志。如何查询以单独获取第一个和最后一个事件?

c++ - 在点云库 (PCL) 中的超体素聚类过程中保留自定义字段

c++ - 使用 Qt 在 C++ 中进行线程串口通信

c++ - 如何支持具有引用的类模板的 move 语义

ios - 如何清除 Objective-C 中的应用程序缓存?

javascript - 如何以编程方式清空浏览器缓存?

c++ - 如何知道环路提前被打破了?