有没有办法完全避免缓存未命中?

20 浏览
0 Comments

有没有办法完全避免缓存未命中?

我在这里阅读了有关缓存工作原理的基本知识:如何以及何时对齐缓存行大小?什么是“缓存友好”的代码?,但这些帖子都没有回答我的问题:有没有一种方法可以完全在缓存中执行某些代码,即在不使用任何访问RAM的情况下(也许仅在从硬盘驱动器中读取文件的初始过程中)?就我所理解的,目前计算的瓶颈主要是内存带宽,“只要在CPU内部,一切都还好”。\n是否有一种方法可以将程序加载到缓存中,并保持在其中直到终止?假设我有一个大小为1MB的编译后的C程序,它需要额外1MB的内存进行科学计算,并且运行时间为5天。是否有一种方法可以标记此代码,以便在评估期间不会从缓存中移出?我在考虑在执行期间提高此代码的优先级或类似的操作。\n换句话说,闲置的计算机使用了多少缓存,它加载了操作系统(比如Ubuntu),然后什么都不做?在闲置期间是否存在过多的缓存使用?如果操作系统除了执行我的程序之外什么都不做,那么我应该期望我的小程序始终在缓存中吗?假设5分钟后启动屏幕保护程序。这会导致大量缓存未命中(从而导致性能严重降低),因为现在它与我的程序竞争缓存空间吗?我的经验是,同时运行几个非要求高的程序(如屏幕保护程序、简单音频播放器、PDF阅读器等)并不会显著降低我的科学计算程序的性能,尽管我本来期望它会一直在缓存中进进出出。问题是:为什么它的速度没有受到影响?使用绝对最简化的操作系统(如果有的话,哪个操作系统?)来改善(或者说保持)计算速度是否有意义?\n为了清楚起见,我们可以假设代码非常简单,比如一堆嵌套的for循环,其中最内部的部分对所有增量变量求和并对97取模。关键是它足够小,可以放入缓存中执行。

0
0 Comments

短答案:不能完全避免缓存未命中。缓存是由操作系统/ CPU维护的,让程序强制停留在缓存中是一个坏主意。假设你同时运行两个程序,并且两个程序都试图强制停留在缓存中,那么会发生混乱,对吧?

这是一个很好的观点。这就是为什么我建议将代码的某些部分“优先处理”而不是其他部分。

无论如何,CPU制造商/操作系统都不会让你这样做。所以答案是不能。

0
0 Comments

在大多数标准架构上,CPU缓存是不可寻址的。即使可以寻址,你期望的性能改进是什么?你认为程序执行时间的百分之多少是用于从主存加载到(L3)缓存中?你应该对程序进行分析以确定它实际上花费时间的地方,而不是对不存在的问题设想解决方案!

我认为x86 CPU可能具有一种硬件配置,可以在没有附加RAM的情况下工作,但这基本上是无关紧要的。

那么我可能误解了。如果你说从主存加载程序到L3缓存所花费的时间与执行程序本身相比微不足道,那么我不明白为什么缓存未命中是一个问题。关于你的第二个备注:程序非常简单,所以我担心在这种情况下分析根本没有帮助。

这确实是关键。在某些情况下,加载确实微不足道,因为程序大部分时间都在做其他事情。在其他情况下,程序可能会在非常大的工作集中乱动,这时主存加载肯定是重要的。猜猜你的示例属于哪一类!(是的,你仍然可以进行分析,例如使用硬件性能计数器)。

这一切都说得通。所以我真正寻找的答案是:“只要程序足够简单,人们可以假设它(几乎)总是在缓存中,因为从RAM加载它是瞬间的。因此,没有必要使用任何花哨的方法来永久保持它在缓存中。”这正是我要找的。我会尝试接受这个(简短但令人信服的)答案。谢谢!

我理解的是,当将堆栈设置在RAM上时,处理器会将堆栈RAM数据提取到L1缓存并与之一起工作。但是当将堆栈设置在TCM上时,数据将始终停留在TCM中(没有从TCM提取到L1缓存),因此运行程序时将始终存在较少的缓存未命中?或者我弄错了?

0
0 Comments

有没有办法完全避免缓存未命中?

CPU缓存未命中有几种不同的类型:强制性未命中、冲突未命中、容量未命中和一致性未命中。

强制性未命中是无法避免的,因为它们发生在第一次引用内存中的位置。所以,不,你绝对不能完全避免缓存未命中。

除此之外,今天典型的L1缓存大小是每个核心32KB/64KB,而L2缓存大小是每个核心256KB。所以1MB的数据也会产生容量未命中或冲突未命中,这取决于缓存的关联性。

强制性未命中可以通过硬件或软件预取来隐藏。引发从内存中加载数据到缓存的指令不会在结果内存总线事务上停顿。当然,这引发了两个问题:这些是否是缓存未命中,无论是从语义上讨论缓存未命中的目的,还是从机械上讨论,给定的CPU微体系结构是否会增加相关性能计数器。根据设计者通常在计数器上提供的非常有限的程度,CPU可能会有所不同。

0