对齐对C++11中的性能真的很重要吗
Does alignment really matter for performance in C++11?
对齐对C++11中的性能真的很重要吗?
Stroustrup的书中有一条建议,要对结构中的成员进行排序从最大到最小。但我想知道是否有人已经进行了测量,以实际查看这是否有任何差异,以及在编写代码时是否值得考虑。
对齐不仅对性能很重要,而且对正确性也很重要。如果数据未正确对齐或访问错误的内存位置,某些体系结构将因处理器陷阱而失败。在其他情况下,对未对齐变量的访问被分解为多次访问和移位(通常在硬件内部,有时通过操作系统陷阱处理程序),从而失去原子性。
建议按大小降序对成员进行排序是为了优化打包/最小化填充所浪费的空间,而不是为了对齐或速度无论您以何种顺序列出成员,都将正确对齐,除非您使用专用杂注(即不可移植的#pragma pack
)或关键字请求不一致的布局。尽管总结构大小受到填充的影响,也会影响速度,但通常还有另一种排序是最优的。
为了获得最佳性能,您应该尝试将一起使用的成员放入同一缓存行,并将不同线程访问的成员放入不同的缓存行。有时,这意味着要在跨线程共享变量自己的缓存行中单独获得它需要大量的填充。但这总比虚假分享带来的业绩打击要好。
只是为了增加本的伟大答案:
以稍后在应用程序中访问的相同顺序定义结构成员将减少缓存未命中,并可能提高性能。如果整个结构不适合一级缓存,这将起作用。
另一方面,将成员从最大到最小排序可能会减少总体内存使用量,这在存储小型结构阵列时可能很重要。
让我们假设,对于一个架构(我不太了解它们,我认为默认设置32位gcc就是这样,有人会在评论中纠正我),这个结构:
struct MemoryUnused {
uint8_t val0;
uint16_t val1;
uint8_t val2;
uint16_t val3;
uint8_t val4;
uint32_t val5;
uint8_t val6;
}
在内存中占用20个字节,而这个:
struct MemoryNotLost {
uint32_t val5;
uint16_t val1;
uint16_t val3;
uint8_t val0;
uint8_t val2;
uint8_t val4;
uint8_t val6;
}
需要12个。这是由于填充而丢失的8个字节,而smallers结构的大小增加了67%。对于这样的结构的大阵列,增益将是显著的,并且仅仅因为使用的内存量,将减少缓存未命中的数量。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- OpenMP阵列性能较差
- 递归列出所有目录中的C++与Python与Ruby的性能
- 大小相等但成员数量不同的结构之间的性能差异
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 为什么constexpr的性能比正常表达式差
- 在类中使用随机生成器时出现性能问题
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 字节真的是最小可寻址单元吗
- 海湾合作委员会 ARM 性能下降
- GCC 和 Clang 代码性能的巨大差异
- 在容量内调整矢量大小时的性能影响
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 通过常量引用传递基本值真的会损害性能吗?
- 与C-string('malloc'+'memcpy')相比,'std::string'的性能真的很差
- 异步记录器真的有助于提高性能吗
- 对齐对C++11中的性能真的很重要吗
- 用c++ cgi进行web开发真的会有巨大的性能提升吗?
- 源代码合并真的能提高C或c++程序的性能吗?
- 标记方法指针/引用参数常量真的会显著影响性能吗