__attribute __((packed))会影响程序的性能吗?

我有一个名为log的结构,里面有13个字符。 在执行sizeof(log)之后,我看到大小不是13而是16。我可以使用__attribute __((packed))将其设置为13的实际大小,但我想知道这是否会影响程序的性能。 它是一种经常使用的结构。

我希望能够读取结构的大小(13而不是16)。 我可以使用宏,但如果这个结构被更改,即添加或删除字段,我希望在不更改宏的情况下更新新大小,因为我认为这很容易出错。 有什么建议吗?

是的,它会影响程序的性能。 添加填充意味着编译器可以使用整数加载指令从内存中读取内容。 如果没有填充,编译器必须单独加载内容并进行位移以获取整个值。 (即使它是x86,这是由硬件完成的,它仍然必须完成)。

考虑一下:如果出于性能原因,编译器为什么会插入随机的,未使用的空间?

不要使用__attribute__((packed)) 。 如果数据结构在内存中,则允许它占用编译器确定的自然大小。 如果用于读/写磁盘,则编写序列化和反序列化函数; 不要简单地在磁盘上存储cpu-native二进制结构。 “打包”结构实际上没有合法用途(或者很少;有关可能不同意见的观点,请参阅此答案的评论)。

是的,它会影响性能。 在这种情况下,如果使用((packed))属性分配此类结构的数组,则大多数结构必须以非对齐方式结束(而如果使用默认包装,则它们都可以在16字节边界上对齐)。 如果它们对齐,那么复制这些结构会更快。

是的,它会影响性能。 具体取决于它是什么以及如何使用它。

未对齐的变量可能跨越两个缓存行。 例如,如果您有64字节的高速缓存行,并且您从13字节结构的数组中读取了一个4字节的变量,那么将有四分之三(4.6%)的可能性将它分布在两行中。 额外缓存访问的代价非常小。 如果你的程序所做的一切都是针对那个变量的,那么4.6%将是性能命中的上限。 如果日志记录占程序工作负载的20%,并且读取/写入该结构的日志记录占50%,那么您已经只占了一小部分。

另一方面,假设需要保存日志,将每个记录缩小3个字节可节省19%,这意味着需要大量内存或磁盘空间。 主内存,特别是磁盘很慢,所以你可能最好包装日志以减小其大小。


至于读取结构的大小而不用担心结构变化,请使用sizeof 。 但是你喜欢做数值常量,无论是const intenum还是#define ,只需添加sizeof

与所有其他性能优化一样,您需要对代码进行概要分析以找到正确的答案。 正确的答案因架构而异 – 以及您如何使用您的结构。

如果您正在创建巨大的arrays,则打包所节省的空间可能意味着拟合和不适合缓存之间的差异。 或者您的数据可能已经适合您的缓存,在这种情况下它将没有任何区别。 如果你在一个STL关联容器中分配大量的结构,用于为你的struct分配存储器,那么它可能根本不重要 – operator new可能会将你的存储分散到最终对齐的东西。

如果您的大多数结构都存在于堆栈中,那么额外的存储可能已经被优化掉了。

为了改变这个简单的测试,我建议建立一个计时器,然后尝试两种方式。 为了进一步优化,我建议使用分析器来识别您的瓶颈并从那里开始。