类成员的顺序会影响访问速度吗?

问题描述 投票:1回答:1

我正在编写一个绝对没有开销的委托库。因此,重要的是尽快完成对函数指针的访问。

所以我的问题是:访问速度是否取决于班级中成员的位置?我听说最重要的成员应该是成员声明中的第一个成员,这对我来说很有意义,因为这意味着类的this指针指向与重要成员相同的地址(假定非虚拟类) )。而如果重要成员位于其他任何位置,则CPU必须通过在类布局中添加this和偏移量来计算其位置。

另一方面,我知道编译器将该地址表示为qword-ptr,其中包含偏移量的信息。

所以我的问题归结为:解决qword-ptr是否需要固定的时间,或者如果偏移量不是0,它会增加吗?在不同的平台上行为是否保持相同?

c++ performance micro-optimization class-members addressing-mode
1个回答
3
投票

大多数机器都有一个加载指令或寻址模式,可以包括很小的恒定位移而不会产生额外费用。

在x86上,对于寻址模式的8位位移部分,[reg][reg + disp8]的开销为1字节。在类似RISC的计算机上,例如ARM,固定宽度的指令意味着加载/存储指令总是有一些位移位(给定指向对象起点的指针,则第一个成员可以全为零)。


在类的最前面将最热的成员归为一类,最好按大小排序以避免填充空白(How do I organize members in a struct to waste the least space on alignment?希望最热的成员都在同一缓存行中。 (如果您的类/结构扩展到第二个缓存行,则希望大多数情况下只有第一行必须在缓存中保持高温,以减少工作集的占用空间。)

如果成员与对象的开头不在同一个page中,则如果还从内存中加载了this,则Sandybridge系列的指针跟踪优化可能会导致额外的延迟。Is there a penalty when base+offset is in a different page than the base?通常,通过乐观地仅将寄存器值用作TLB的输入,可以将L1d负载使用等待时间从5个周期减少到4个周期,以解决[rdi + 0..2047]这样的模式,但是如果猜错了就必须重试。 (不是管道刷新,只是在没有快捷方式的情况下重试该加载uop。)


[注意,功能指针主要取决于分支预测的有效性,而访问等待时间仅对check预测重要(如果错误,则开始分支恢复)。即,推测性执行+分支预测隐藏了执行顺序混乱的CPU中的延迟控制依赖性。

© www.soinside.com 2019 - 2024. All rights reserved.