为什么在CPU缓存中缓存共享变量



我正在尝试理解Java内存模型,但未能获得有关CPU Caches的观点。

据我所知,在JVM中,我们有以下位置存储本地和共享变量:

local variables -- on thread stack
shared variables -- in memory, but every CPU cache has a copy of it

所以我的问题是:为什么将局部变量存储在堆栈上,而(缓存)共享变量在CPU缓存中?为什么不相反(假设CPU高速缓存太昂贵而无法存储两者),我们可以在CPU缓存中缓存本地变量,而只是从内存中获取共享变量?这是Java语言设计还是计算机体系结构的一部分?

进一步:就像" CPU缓存"听起来很简单,如果几个CPU共享一个缓存怎么办?在具有多层缓存的系统中,将存储共享变量的副本的哪个级别的缓存?此外,如果超过1个线程在同一CPU核心中运行,是否意味着它们共享相同的缓存共享变量,因此即使没有定义共享变量的volatile,该变量的访问仍然是立即的在同一CPU上运行的其他线程可见?

" local"one_answers"共享"变量在您的代码上下文之外毫无意义。他们不会影响国家缓存的位置,甚至没有影响。从您的州存储何处思考或理由甚至没有用;JMM存在的全部原因是这样的细节,这些细节因体系结构而异,并未暴露于程序员。通过依靠低级硬件详细信息,您提出了有关JMM的错误问题。它对您的应用程序没有用,它使其变得脆弱,更容易破裂,更难推理和便携式。

也就是说,通常,您应该假设任何计划状态(如果不是全州)都有资格被缓存。事实是,缓存实际上并不重要,只是任何东西都可以,无论是原始类型或参考类型,甚至是由几个字段封装的状态变量。无论线程运行什么指令(这些说明也因架构而异 - 当心!),这些说明默认在CPU上以确定与Cache相关的内容以及与CACHE不相关的内容;程序员不可能自己执行此操作(尽管 可能会可能会缓存状态变量,请查看错误的共享是什么)。

再次,我们还可以对X86进行更多的概括,因为p/alus可以在寄存器上放置可能,因为p/alus将能够与它们合作最快。不过还有其他事情。如果原始图是核心本地,则可能会将其移至L1/2缓存,当然,它们很可能很快被覆盖。如果CPU认为将来会有上下文切换,或者不能将状态变量放在共享的L3上,或者不能。硬件专家需要对此做出回应。

理想情况下,状态变量将存储在最接近的缓存(寄存器,L1/2/3,然后是主存储器)到处理器单元。不过,CPU决定了。不可能在Java级别上进行有关缓存语义的推理。即使启用了超线程(我不确定AMD当量是什么),也不允许线程共享资源,即使这样,如果这些资源是什么,请回想一下,可见性并不是与共享状态变量相关的唯一问题;在处理器执行管道的情况下,您仍然需要适当的说明来确保正确的订购(即使您在CPU上摆脱了读/写缓冲之后,无论是hwsync还是适当的栅栏或其他围栏。/p>

再次,关于缓存属性的推理无用,这既是因为JMM处理的操作,因为它是不确定的,在哪里/何时/何时/何时缓存。此外,即使您确实知道何处/何时/什么问题,您仍然无法推论数据可见性;无论如何,所有缓存都以相同的方式处理缓存的数据,您将需要依靠处理器更新ME(O)SI状态之间的高速缓存状态,指令排序,加载/商店缓冲,写入Back/take等。而且,您仍然还没有处理在OS和JVM级别上可能发生的问题。同样,幸运的是,JDK允许您使用基本工具,例如volatilefinal和原子,它们在所有平台上始终如一地工作,并生成可预测且容易(er)的代码,以使用。

最新更新