CPU数据缓存何时更新? 以这些情况为例:
示例1:
SomeObject* pObject;
//[...]
pObject->member = variable;
示例2:
SomeObject object;
object.member = variable;
如何在这些示例中更新缓存? 它是一样的吗?或者在数据访问方面存在差异,因为示例1使用指针而示例2不使用?
答案 0 :(得分:2)
在示例1 中,CPU首先需要访问指针本身,然后是实际对象。
在示例2 中,CPU可以直接访问堆栈中的对象,因此很有可能它已经被缓存,因为堆栈上的其他变量具有良好的局部性。
访问的所有内存位置将在d-cache中结束,直到被最近访问的位置替换。在多核CPU中不同核心之间维持和同步d-cache的确切程度如何是特定CPU的实现细节,并且涉及“高速缓存行”(通常是高速缓存“单元”的64位块)和各种高速缓存一致性协议。
话虽如此,您应该意识到多线程环境中性能的严重下降可能是这些实现细节的结果,称为false sharing。
一般来说,追逐指针比仅仅线性访问内存要慢,因为它的位置较差(因此缓存效率较低)和可预测性较差(因此CPU无法有效利用预取)。
答案 1 :(得分:0)
这在很大程度上取决于它如何编译以及您正在使用的架构。如果您想要更好的缓存性能,请尝试按顺序最小化不必要的膨胀和访问。
SomeObject* pObject;
pObject->member = variable;
pObject
指针pObject->member
和variable
应该在缓存中结束。
SomeObject object;
object.member = variable;
object
(构造函数中使用的所有成员)和variable
应该在缓存中结束。