C++ 内存访问和缓存

C++ 内存访问和缓存,c++,memory,C++,Memory,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不使用指针?

这在很大程度上取决于它的编译方式和您使用的体系结构。如果您想要更好的缓存性能,请尽量减少不必要的膨胀,并按顺序进行访问

SomeObject* pObject; 
pObject->member = variable;
pObject
指针、
pObject->member
变量应在缓存中结束

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

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

SomeObject object; 
object.member = variable;
  • 指针位于堆栈上,这使得它很有可能已经在数据缓存中,因为堆栈上的其他变量具有良好的局部性。它甚至可能在登记册上
  • 对象与指针位于同一堆栈帧上是不常见的—它要么位于堆上(位于“随机”位置),要么位于较浅的堆栈帧上,并且有可能不再位于d-cache中,因此您更有可能支付内存延迟惩罚
在示例2中,CPU可以直接访问堆栈上的对象,因此由于堆栈上的其他变量具有良好的局部性,因此它很有可能已经被缓存

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

也就是说,您应该注意到多线程环境中的性能严重下降,这可能是这些实现细节的结果,称为


一般来说,跟踪指针比线性访问内存慢,因为它具有更差的局部性(因此缓存效率较低)和更差的可预测性(因此CPU无法有效利用预取)。

pObject->member=variable。它不是堆栈就是堆。什么是缓存?什么缓存?什么是
D-Cache
SomeObject*poobject=newsomeobject()
pObject->member=变量数据缓存=数据缓存。答案将取决于对象是什么以及它存储在哪里……取决于cpu是如何设计的,编译器是如何优化代码的,等等。如果优化器将其中任何一个放入寄存器中,它们都不会最终进入缓存。@MikeDeSimone说得好,我稍微改变了措辞。如果pSomeObject和variable在遥远的记忆中呢?它们可以同时在缓存中还是一个接一个地在缓存中?@tiagocsta是的,它们可以(同时在缓存中)。它们将在不同的“缓存线”中。哦,我明白了。。。你能给我推荐一本解释缓存工作原理的书吗?我读过《英特尔编程指南》,但这些指南没有多大帮助,因为它们太高了。对不起,蒂亚戈,我不能——我自己并没有从任何一本书中学习过,多年来我从许多来源收集了这些知识。话虽如此,如果您对性能非常感兴趣,我强烈建议您在和观看Herb Sutter的一些讲座,例如:“机器架构:您的编程语言从未告诉过您的事情”