我最近了解了结构的尺寸和对齐方式。我非常熟悉如何使用以及alignas()说明符的工作原理。我已经看到了正确使用的例子(关于语义,而不是现实用例)以及它改变类型/变量大小的方式。
但是,我不知道何时它在我的代码中很有用。当开发人员手动指定数据对齐时,您能列出一些用例吗?
答案 0 :(得分:9)
有很多用例,其中alignas在多线程应用程序中很方便,这些应用程序对延迟敏感。例如。高频交易应用程序。
Alignas可以更加严格地控制CPU缓存上对象布局的方式,从而更快地访问对象。最佳使用的目标如下,这是使用alignas的用例
如何使用alignas对齐缓存行有助于
使用1 - 避免不必要的缓存行数据失效
您可以使用alignas来保持单独线程使用的地址或对象在不同的缓存行上运行,这样一个线程就不会无意中使另一个核心的缓存行无效。
如何发生这种情况: 考虑当进程中的线程在核心0上运行并写入地址xxxx时的情况。此地址现在加载到核心0的L1缓存中。 线程号2访问地址xxxx + n个字节。现在,如果这两个地址碰巧都在同一个高速缓存行上,那么线程2的任何写入都将不必要使核心0的高速缓存行无效。因此,线程0被延迟,直到高速缓存行无效并再次加载。这妨碍了多线程环境中的性能。
使用2 将对象与单独的缓存行对齐,以使对象不会分布在多个缓存行中。这节省了CPU周期。例如。如果您的对象大小是例如。 118字节,最好将其与64字节对齐,因为在大多数处理器上,缓存行大小现在是64字节。
如果不这样做,您的对象可能会在64字节缓存行上按如下方式布局。 (例如,如果对象具有118字节的实际大小并且具有自然对齐,则大小变为4的倍数,因此为120字节)
缓存行1< -----对象1 60Bytes - > < ---你的对象4>字节---------->
缓存行2< ---------您的对象64字节--------------------------------- >
高速缓存行3< -----您的对象52字节-----> < ---一些其他对象12字节 - >
由于CPU读取多个缓存行,因此将以3个cpu周期读取您的对象。如果要优化它,请考虑使用alignas(64)。这样,您的对象将始终分布在2个缓存行上。
<强>注意事项强> 请注意,在考虑对齐之前,您需要仔细检查对象。原因是错误的方法会导致更多的填充,从而更多地浪费L2缓存。有一些简单的技术可以按顺序排列数据成员,以避免浪费。
希望这会有所帮助,祝你好运!