内存访问和缓存

时间:2011-10-15 21:59:28

标签: c++ memory

CPU数据缓存何时更新? 以这些情况为例:

示例1:

SomeObject* pObject; 
//[...]
pObject->member = variable;

示例2:

SomeObject object; 
object.member = variable;

如何在这些示例中更新缓存? 它是一样的吗?或者在数据访问方面存在差异,因为示例1使用指针而示例2不使用?

2 个答案:

答案 0 :(得分:2)

示例1 中,CPU首先需要访问指针本身,然后是实际对象。

  • 指针位于堆栈上,由于堆栈上的其他变量具有良好的局部性,因此它很可能已经存在于数据缓存中。它甚至可能在注册。
  • 对象与指针位于同一堆栈帧上是不常见的 - 它位于堆上(在“随机”位置)或较浅的堆栈帧上,并且有可能它不再在d中-cache所以你更有可能支付内存延迟惩罚。

示例2 中,CPU可以直接访问堆栈中的对象,因此很有可能它已经被缓存,因为堆栈上的其他变量具有良好的局部性。

访问的所有内存位置将在d-cache中结束,直到被最近访问的位置替换。在多核CPU中不同核心之间维持和同步d-cache的确切程度如何是特定CPU的实现细节,并且涉及“高速缓存行”(通常是高速缓存“单元”的64位块)和各种高速缓存一致性协议。

话虽如此,您应该意识到多线程环境中性能的严重下降可能是这些实现细节的结果,称为false sharing

一般来说,追逐指针比仅仅线性访问内存要慢,因为它的位置较差(因此缓存效率较低)和可预测性较差(因此CPU无法有效利用预取)。

答案 1 :(得分:0)

这在很大程度上取决于它如何编译以及您正在使用的架构。如果您想要更好的缓存性能,请尝试按顺序最小化不必要的膨胀和访问。

SomeObject* pObject; 
pObject->member = variable;

pObject指针pObject->membervariable应该在缓存中结束。

SomeObject object; 
object.member = variable;

object(构造函数中使用的所有成员)和variable应该在缓存中结束。