【问题标题】:C++ alignment (when to use alignas)C++ 对齐(何时使用对齐)
【发布时间】:2018-01-10 17:46:50
【问题描述】:

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

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

【问题讨论】:

  • 与需要特定对齐的设备对话;使用 SSE/MMX/等;利用当数据以某种方式对齐时工作速度更快的 CPU 功能——例如确保给定的 `char s[128]' 不会在两个 cpu 缓存行之间拆分

标签: c++ struct alignment


【解决方案1】:

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

Alignas 可以更严格地控​​制对象在 CPU 缓存上的布局方式,从而更快地访问对象。优化使用的目标如下,这是使用 alignas 的用例

  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 Bytes ---------->
缓存行 2
缓存第 3 行

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

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

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

【讨论】:

  • 你赢得了我的“最佳答案”奖)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 2015-03-25
  • 2014-08-10
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
相关资源
最近更新 更多