C++关键字alignof和alignas的实际应用案例

3

我刚学习了C++中的alignofalignas关键字,但是我无法想象开发人员何时需要使用这些关键字。

请问有没有人知道这些关键字的实际用途?


1
内存对齐:如何使用alignof / alignas? - Ruks
这个回答解决了你的问题吗?内存对齐:如何使用alignof/alignas? - Adrian Mole
1
不,我不认为它会。 - Waqar
3个回答

5
alignas说明符的常见用法是在通过队列(例如事件或任务队列)在不同线程之间传递多个对象时避免伪共享。当多个线程实际上访问不同的对象时,它们会竞争相同的缓存行,从而导致伪共享。由于性能下降,通常不希望出现这种情况。
例如-假设缓存行大小为64字节-给定以下Event类:
struct Event {
   int event_type_;
};

Event的对齐方式将与其数据成员event_type_的对齐方式相对应。假设int的对齐方式为4字节(即alignof(int)计算结果为4),则最多可以将16Event对象放入单个高速缓存行中。因此,如果您有一个类似于以下队列:

std::queue<Event> eventQueue;

当一个线程将事件推入队列的后面,另一个线程从前面拉取事件时,它们可能会竞争相同的缓存行。然而,通过在 Event 上正确使用 alignas 指定符:

struct alignas(64) Event {
   int event_type_;
};

这样,一个“事件(Event)”对象总是对齐在缓存行边界上,以便缓存行最多包含一个“事件”对象。因此,当访问不同的“事件”对象时,两个或更多线程永远不会竞争相同的缓存行(如果多个线程正在访问相同的“事件”对象,则它们显然会竞争相同的缓存行)。

2

基于我的经验,以下是一些实际应用场景:

  • 在嵌入式系统中为网络数据包编写专用分配器
  • 解决嵌入式系统专用CPU中的bug问题
  • 针对缓存使用进行性能优化
  • 将C++对象的一部分提供给需要具体对齐方式的C库

1

指针上的备用内存:如果指向某个类型的指针总是以零结尾,因为该类型的对齐方式,则始终为零的位可以用于存储其他内容。例如:

class Small { Aligned * ptr; bool b; }; // suppose having many instances

在64位架构上,这将至少需要8+1个字节,但可以通过仔细地将指针和布尔值联合起来压缩为8个字节。在使用指针之前,您必须进行位掩码操作,但这是一条非常快速的指令。这是内存和CPU之间的权衡。

1
编译器实际上不允许这样做。指针是平凡类型,因此我可以通过将memcpy分配到它们来对它们进行分配。这不能允许修改任何其他对象的值,包括b。但如果它们共享内存,那么就会出现这种情况。填充字节是对象表示的一部分,因此不能随意被某个其他对象使用(除非该对象大小为零)。 - Nicol Bolas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接