【问题标题】:Is std::make_unique<T[]> required to return aligned memory?是否需要 std::make_unique<T[]> 返回对齐的内存?
【发布时间】:2014-05-19 08:43:37
【问题描述】:
  • 是唯一指针array_ptr拥有的内存吗:

    auto array_ptr = std::make_unique<double[]>(size);
    

    对齐到 sizeof(double) alignof(double) 边界(即标准是否需要正确对齐)?

  • 数组的第一个元素是缓存行的第一个元素吗?

  • 否则:在 C++14 中实现此目的的正确方法是什么?

动机(更新):我计划在数组上使用 SIMD 指令,因为缓存行是我所知道的每个单一架构上的基本内存单元,我宁愿正确分配内存,以便第一个元素数组位于缓存行的开头。请注意,只要元素正确对齐(与缓存行之间元素的位置无关),SIMD 指令就可以工作。但是,我不知道这是否有影响,但我可以猜到是的,确实有。此外,我想在内核中的原始内存上使用这些 SIMD 指令。这是内核的优化细节,所以我不想分配例如__int128 而不是 int。

【问题讨论】:

  • 听起来你想要对齐的存储而不是对齐的类型。类型总是至少和它们的对齐一样大,这根本不是你想要的。也许试试std::aligned_storage
  • @KerrekSB 我猜对齐存储就是我所说的对齐内存的意思。很抱歉与 sizeof 与 alignof 混淆(我不知道 alignof)。

标签: c++ arrays c++14


【解决方案1】:
  • 您“通常”获得的所有对象都经过适当对齐,即在alignof(T) 对齐(不必与sizeof(T) 相同。这包括动态数组。(通常,分配器::operator new 将只需返回一个最大对齐的地址,这样就不必担心内存是如何使用的。)

  • C++ 中没有缓存行。这是您需要自己处理的平台特定问题(但alignas 可能会有所帮助)。

  • 尝试alignas 加上静态检查是否有效(因为对过度对齐类型的支持取决于平台),否则只需添加手动填充。您并不真正关心您的数据是否位于缓存行的开头,只关心没有两个数据元素位于同一缓存行上。

值得强调的是,对齐实际上并不是一个可以在 C++ 中直接检查的概念,因为指针不是数字。它们可转换为数字,但除了可逆之外,这种转换通常没有意义。你需要像std::align 这样的东西来实际说“我已经对齐内存”,或者直接在你的类型上使用alignas

【讨论】:

  • “你并不关心你的数据是否在缓存行的开头,只是没有两个数据元素在同一个缓存行上。”例如虚假分享你是对的。但是我想在数组上使用 SIMD 指令,我不知道第一个元素在缓存行中间随机开始的效果。
  • @gnzlbg:这是一个非常不同的问题!
  • 如果我的数据正确对齐,即使第一个元素不在缓存行的开头,它也应该仍然有效。但由于缓存行是我所知道的每种架构中的基本内存单元,我宁愿“做对”并将我的第一个元素放在一个开头。
  • 您能否展示如何对双精度数组的 unique_ptr 进行静态检查或如何直接使用 alignas? (或者只是给我举个其他地方的例子?)。
  • 听起来您从问题 X 开始,现在我们在问题 Y。一个新问题可能会得到一些新答案。
猜你喜欢
  • 1970-01-01
  • 2017-02-15
  • 2017-04-20
  • 2010-12-26
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多