C++对齐方式(何时使用对齐方式)

C++ alignment (when to use alignas)

本文关键字:方式 对齐 C++ 何时使      更新时间:2023-10-16

我最近了解了结构的大小和对齐方式。我非常熟悉如何使用以及 alignas(( 说明符的工作原理。我已经看到了正确使用的示例(关于语义,而不是现实生活中的用例(以及它更改类型/变量大小的方式。

但是,我不知道它何时在我的代码中有用。您能否列出一些用例,开发人员何时应手动指定数据的对齐方式?

在很多用例中,alignas 在对延迟敏感的多线程应用程序中很方便。例如。高频交易应用程序。

Alignas 可以更严格地控制对象在 CPU 缓存上的布局方式,以便更快地访问对象。最佳使用目标如下,这是使用对齐的用例

  1. 您希望避免缓存行中的数据不必要地失效
  2. 您希望优化 CPU 读取,以便可以节省 CPU 周期的浪费。

使用 alignas 与缓存行对齐有何帮助
使用 1 - 避免缓存行中的数据不必要地失效您可以使用 alignas 来保持单独线程使用的地址或对象在单独的缓存行上运行,以便一个线程不会无意中使另一个内核的缓存行无效。

如何发生:考虑当进程中的线程在核心 0 上运行并写入地址(例如 xxxx(的情况。此地址现在加载到核心 0 的 L1 缓存中。 线程 2 正在访问地址 xxxx + n 字节。现在,如果这两个地址恰好在同一缓存行上,则线程 2 的任何写入都将不必要地使核心 0 的缓存行无效。因此,线程 0 将延迟,直到缓存行失效并再次加载。这会影响多线程环境中的性能。

使用 2 将对象对齐以分隔缓存行,以便对象不会分布在多个缓存行中。这样可以节省 CPU 周期。例如。如果你的对象大小是例如。118 字节,最好将其对齐为 64 字节,因为在大多数处理器上,缓存行大小现在为 64 字节。

如果不这样做,您的对象可能会在 64 字节的缓存行上按如下方式布局。(例如,假设对象的实际大小为 118 字节,并且自然对齐,大小变为 4 的倍数,因此为 120 字节(

缓存行 1<-----对象 1 60 字节 --> <---您的对象 4> 字节---------->
缓存行 2<--------- 您的对象 64 字节--------------------------------->
缓存行 3 <----- 您的对象 52 字节 -----> <--- 其他一些对象 12 字节 -->

由于 CPU 在多个缓存行中读取,因此将在 3 个 CPU 周期内读取您的对象。如果要优化它,请考虑 alignas(64(。这样,您的对象将始终分布在 2 个缓存行上。

注意事项请注意,在考虑对齐之前,您需要仔细检查您的对象。错误的方法会导致更多的填充,从而浪费更多的二级缓存。有一些简单的技术可以按顺序排列数据成员,以避免浪费。

希望这有帮助,祝你好运!