何时更新CPU数据缓存? 把这些情况作为例子:内存访问和缓存
实施例1:
SomeObject* pObject;
//[...]
pObject->member = variable;
实施例2:
SomeObject object;
object.member = variable;
如何缓存在这些实施例更新? 它是一样的吗?或者在数据访问方面存在差异,因为示例1使用了指针而示例2没有?
何时更新CPU数据缓存? 把这些情况作为例子:内存访问和缓存
实施例1:
SomeObject* pObject;
//[...]
pObject->member = variable;
实施例2:
SomeObject object;
object.member = variable;
如何缓存在这些实施例更新? 它是一样的吗?或者在数据访问方面存在差异,因为示例1使用了指针而示例2没有?
在示例1,CPU首先需要访问指针本身,然后是实际的对象。
在例2,CPU可以直接访问对象,它是在栈上,从而它具有它已经由于良好局部性与缓存到其它变量堆栈上的好机会。
所有访问的内存位置都将在d-cache中结束,直到被最近访问的位置取代。在多核CPU中不同内核之间维护和同步d-cache究竟是一个特定CPU的实现细节,涉及“缓存行”(通常是64位块,即缓存的“单元”)和各种缓存一致性协议。这就是说,您应该意识到多线程环境中性能的严重下降,这可能是这些实现细节的结果,称为false sharing。一般来说,追逐指针比线性访问内存要慢,因为它具有更差的局部性(因此缓存效率较低)和较差的可预测性(因此CPU无法有效地利用预取)。
pSomeObject和变量在远处的内存中怎么办?他们可以在同一时间或一个接一个地在缓存中吗? –
@TiagoCosta是的,他们可以(同时在缓存中)。他们将在不同的“缓存行”。 –
哦,我明白了......你能推荐一些解释缓存工作原理的书吗?我已阅读英特尔编程指南,但它们并不是非常有用,因为它们太高级 –
这很大程度上取决于它如何编译以及您使用的架构。如果你想要更好的缓存性能,尽量减少不必要的膨胀和访问顺序。
SomeObject* pObject;
pObject->member = variable;
pObject
指针,pObject->member
和variable
应在缓存中结束。
SomeObject object;
object.member = variable;
object
(全部在构造函数中使用其成员)variable
,并应在缓存中结束。
如果优化器将这些寄存器中的任何一个放入寄存器中,它们将不会在缓存中结束。 –
@MikeDeSimone好点,我已经稍微改变了措辞。 – Pubby
'pObject-> member = variable;'。它可以是堆栈或堆栈。什么是缓存的东西? – Mahesh
什么缓存?什么是“D-Cache”? – ildjarn
'SomeObject * pObject = new SomeObject();' 'pObject-> member = variable;' – ruakh