c++ - "Packing"结构对性能有何影响

标签 c++ performance

开始微优化并不是我的目标,所以如果这就是结果,我会很乐意放弃这个问题。但我即将开始做出一些设计决策,并希望了解更多信息。

我正在读取和处理一种文件格式,其中包含大量以定义明确的格式记录的数据结构。我在代码中将它们表示为结构。

现在,如果我用 #pragma pack(1) 将结构打包成一个 1 字节对齐,我可以从 IO 流中直接读取结构到结构指针。这很方便。如果我不打包结构,我可以一个一个地fread 字段或一次fread block 然后reinterpret_cast 结构字段一个接一个,这可能会很快变老。

作为引用,这些结构将(可能)被成千上万的人读取,并且可以对它们进行一些数字运算。它们主要由无符号 16 位整数(约 60%)、无符号 32 位整数(约 30%)和一些 64 位整数组成。

所以手头的问题是,我...

  • 进行数以万计的微小调用害怕
  • 读取 block 并复制相关字节?
  • 打包结构并直接阅读它们?

最佳答案

最终,解决方案 A 和解决方案 B 之间的性能差异只能通过基准测试来确定。在互联网上询问会给您不同的结果,这些结果可能反射(reflect)也可能不反射(reflect)您的情况。

当您“错位”数据时会发生什么情况是处理器需要对一份数据进行多次读取 [并且同样适用于写入]。究竟需要多少额外时间取决于处理器——一些处理器不会自动执行,因此运行时系统将捕获“错误读取”并在某些仿真层中执行读取[或者,在某些处理器中,简单地杀死“未对齐内存访问”的过程]。显然,采取陷阱并执行几个读取操作然后返回调用代码会对性能产生相当大的影响 - 它很容易比对齐读取操作多花费数百个周期。

在 x86 的情况下,它“像您期望的那样工作”,但通常会增加 1 个额外的时钟周期 [假设数据已经在 L1 缓存中]。一个时钟周期在现代处理器中不是很多,但是如果循环的迭代次数为 10000000000000 次并且读取未对齐的数据 n 次,那么您现在已将 n * 10000000000000 个时钟周期添加到执行时间,这可能很重要。

其他替代方案也会对性能产生影响。进行大量小读取可能比进行一次大读取慢很多。从性能的角度来看,转换功能可能更好。

再次重申,请不要将此视为“给定的”,您确实需要比较不同的解决方案(或选择一个,如果性能不差,代码也不难看,那就放弃吧在那)。我相当相信您可以为您建议的“最佳”三种解决方案中的每一种找到案例。

另请记住,#pragma pack 是特定于编译器的,并且实现允许您在“Microsoft”和“gcc”解决方案之间进行选择的宏并不容易,例如。编辑:看起来最近的 gcc 版本确实支持这个选项——但不是所有的编译器都支持。

关于c++ - "Packing"结构对性能有何影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16108956/

相关文章:

c++ - rdbuf() 奇怪的行为

javascript - JavaScript 中最快的 MD5 实现

java - 有什么办法可以知道C++模板中的函数是什么?

c++ - GCC 与 Clang 关于临时绑定(bind)到另一个临时的右值引用的生命周期

c++ - Cygwin 警告命令

performance - 搜索和排序立方体面积的算法

performance - 在 * 元素上使用背面可见性

安卓动画变慢

c - 基数排序优化

c++ - N选K、K-N、K-2N等,递归中递归