【问题标题】:How use alignof to force alignment for a heap allocation?如何使用 alignof 强制对齐堆分配?
【发布时间】:2014-02-19 23:40:35
【问题描述】:

我想强制特定的堆分配返回一个 64 字节对齐的地址,因为那是缓存线边界。我以为我可以这样做

int *p = new alignas(64) int;

但我的编译器似乎都没有给 p 一个 64 倍数的地址。这是我正在检查的方式:

#include <iostream>

int main()
{
  int *p = new alignas(64) int;
  std::cout << long(p) % 64 << '\n';    // should print 0
}

我一定是做错了什么。但是什么?

【问题讨论】:

  • 两件事:a) 对过度对齐类型的支持依赖于实现,b) 非常迂腐,您要检查的只是 转换后的值 是否可整除。就语言而言,除了通过新的对齐语言功能外,您没有“指针对齐”的概念。指针不是整数,它们只能与整数相互转换。
  • 请注意,我不是在检查指针的对齐方式(即&amp;p 的值),而是在检查它所指向的对齐方式。是的,我同意,我正在检查转换为 long 的指针的值,但是有没有更好的方法来查看我的对齐请求是否得到满足?
  • 是的,新的语言功能非常丰富,可能有你需要的东西,例如std::align。在 C++11 之前,没有对齐内存的标准概念,这就是添加它的原因。您之前必须使用特定于平台的方法。
  • @KeithThompson:我没有将其打印为long,我正在对其进行算术运算以查看它是否是 64 的倍数。
  • 我删除了我的评论。但如果可用,您可能应该转换为uintptr_t(在&lt;cstdint&gt; 中声明)。在某些实现中,int* 大于 long

标签: c++ c++11 memory-alignment


【解决方案1】:

new 运算符为分配空间而调用的分配器“假定返回指向存储的指针,该指针针对具有基本 对齐”(§3.7.4.1/2;引用来自 §5.3.4/11)。alignas(64) 可能不是您的编译器和环境的“基本对齐”,因此分配函数不需要尊重它。

注意分配函数只传递请求的空间量;它不知道正在请求什么对齐。因此,它无法调整其结果以适应特殊需要。

alignas 类型说明符设计用于处理静态和自动对象。对于这样的对象,如果它是基本的,则必须尊重所请求的对齐,并且在理想的世界中,如果编译器不能保证扩展对齐会得到尊重,它将产生错误消息。 (不过,我不认为它有义务这样做;gcc 和 clang 都会生成可执行文件,如果请求大量堆栈对齐,则会出现段错误。)

【讨论】:

  • 我刚刚用 g++ 4.8 进行了测试,没有任何东西对齐超过 8 个字节(无论如何这是标准的内存对齐)。因此,我看不到该关键字的用处!在 x86 上,有些寄存器需要 128 个字节对齐的内存(以及 64 个作为 OP 使用的),但不知何故,这对于该目的完全没用。太糟糕了。我什至尝试了一个结构和一个类,最终都错位了。如果它只适用于已经正确对齐的类型,那么没有必要添加到语言中!
  • @AlexisWilke:它是为堆栈分配的(自动)对象设计的。 (即使在那里,它也不能保证工作,但如果编译器不能保证对齐,它应该提供编译时错误。)使用new 分配的所有对象都具有相同的对齐方式(至少,使用默认分配函数)。我在 gcc 4.8/linux 上尝试过,它在 alignas(8192) 上运行良好。
  • 啊……这行得通。太糟糕了,它也不用新的。我想我们仍然会使用旧的 memalign() 函数。
【解决方案2】:

请求比您需要的多 64 个字节,然后在分配的空间内生成一个缓存对齐地址。最后注意释放整个分配的内存。

【讨论】:

  • 我知道还有其他方法可以做我想做的事情(例如,使用std::aligned_storagestd::align),但我真的很想了解我为什么使用alignas不工作。
  • alignas 作用于简单的变量,而不是新的
  • 天哪,我一无所知 - std::aligned 存储看起来非常好,std::align 符合我的建议,但更整洁
  • 顺便说一下,std::aligned_storage 只是alignas 的简写,因此它也不适用于newstd::align 是你想要的。
  • 其实你只需要(alignment - 1)字节的额外空间。
猜你喜欢
  • 2014-03-20
  • 2013-06-10
  • 1970-01-01
  • 2021-12-26
  • 2011-06-16
  • 2019-02-19
  • 2020-03-16
相关资源
最近更新 更多