alignof 和 alignas C++ 关键字的实际用例
Practical use cases for alignof and alignas C++ keywords
我刚刚了解了 alignof
和 alignas
C++ 关键字,但我想不出开发人员想要使用这些关键字的任何实际案例。
有人知道这些关键字的任何实际用例吗?
我的实际使用案例:
- 为嵌入式系统中的网络数据包编写专门的分配器
- 解决嵌入式系统专用 CPU 中的错误
- 关于缓存使用的性能优化
- 将部分 C++ 对象提供到需要具体对齐的 C 库中
alignas
说明符的一个常见用例是您希望通过队列(例如,事件或任务队列)在不同线程之间传递多个对象,同时避免 false sharing .多个线程在实际访问不同对象时竞争相同的 缓存行 会导致错误共享。由于性能下降,通常不希望这样做。
例如 – 假设缓存行大小为 64 字节 – 给定以下 Event
class:
struct Event {
int event_type_;
};
Event
的对齐方式将与其数据成员event_type_
的对齐方式相对应。假设 int
的对齐方式是 4 字节(即 alignof(int)
的计算结果为 4),那么最多 16 Event
个对象可以放入单个缓存行。所以,如果你有这样的队列:
std::queue<Event> eventQueue;
如果一个线程将事件推入队列后部,而另一个线程从队列前部拉取事件,我们可能会让两个线程竞争同一个缓存行。但是,通过在 Event
:
上正确使用 alignas
说明符
struct alignas(64) Event {
int event_type_;
};
这样,Event
对象将始终在缓存行边界上对齐,以便缓存行最多包含一个 Event
对象。因此,两个或多个线程在访问不同的 Event
对象时永远不会竞争同一个缓存行(如果多个线程正在访问同一个 Event
对象,它们显然会竞争同一个缓存行)。
指针上的备用内存:如果指向某个类型的指针由于该类型的对齐而始终以零结尾,那么那些始终为零的位可用于存储其他内容。示例:
class Small { Aligned * ptr; bool b; }; // suppose having many instances
在 64 位架构上至少需要 8+1 个字节,但可以通过仔细合并 ptr 和 bool 将其压缩到 8 个字节。在使用 ptr 之前你必须对其进行位掩码,但这是一个非常快的指令。
它是内存和 cpu.
之间的权衡
我刚刚了解了 alignof
和 alignas
C++ 关键字,但我想不出开发人员想要使用这些关键字的任何实际案例。
有人知道这些关键字的任何实际用例吗?
我的实际使用案例:
- 为嵌入式系统中的网络数据包编写专门的分配器
- 解决嵌入式系统专用 CPU 中的错误
- 关于缓存使用的性能优化
- 将部分 C++ 对象提供到需要具体对齐的 C 库中
alignas
说明符的一个常见用例是您希望通过队列(例如,事件或任务队列)在不同线程之间传递多个对象,同时避免 false sharing .多个线程在实际访问不同对象时竞争相同的 缓存行 会导致错误共享。由于性能下降,通常不希望这样做。
例如 – 假设缓存行大小为 64 字节 – 给定以下 Event
class:
struct Event {
int event_type_;
};
Event
的对齐方式将与其数据成员event_type_
的对齐方式相对应。假设 int
的对齐方式是 4 字节(即 alignof(int)
的计算结果为 4),那么最多 16 Event
个对象可以放入单个缓存行。所以,如果你有这样的队列:
std::queue<Event> eventQueue;
如果一个线程将事件推入队列后部,而另一个线程从队列前部拉取事件,我们可能会让两个线程竞争同一个缓存行。但是,通过在 Event
:
alignas
说明符
struct alignas(64) Event {
int event_type_;
};
这样,Event
对象将始终在缓存行边界上对齐,以便缓存行最多包含一个 Event
对象。因此,两个或多个线程在访问不同的 Event
对象时永远不会竞争同一个缓存行(如果多个线程正在访问同一个 Event
对象,它们显然会竞争同一个缓存行)。
指针上的备用内存:如果指向某个类型的指针由于该类型的对齐而始终以零结尾,那么那些始终为零的位可用于存储其他内容。示例:
class Small { Aligned * ptr; bool b; }; // suppose having many instances
在 64 位架构上至少需要 8+1 个字节,但可以通过仔细合并 ptr 和 bool 将其压缩到 8 个字节。在使用 ptr 之前你必须对其进行位掩码,但这是一个非常快的指令。 它是内存和 cpu.
之间的权衡