Performance 缓存关联性如何影响性能
我正在阅读Andrey Akinshin的“Pro.NET基准测试”,有一件事让我感到困惑(第536页)——解释如何影响性能。在一次测试中,作者使用了Performance 缓存关联性如何影响性能,performance,caching,cpu,cpu-cache,Performance,Caching,Cpu,Cpu Cache,我正在阅读Andrey Akinshin的“Pro.NET基准测试”,有一件事让我感到困惑(第536页)——解释如何影响性能。在一次测试中,作者使用了ints的3个方形数组1023x1023、1024x1024、1025x1025,并观察到1024x1024情况下访问第一列的速度较慢 作者解释(背景信息,CPU为Intel,具有32KB内存的一级缓存,8路关联): 当N=1024时,这个差值正好是4096字节;它等于 临界跨步值。这意味着从第一个 列匹配一级缓存的相同八条缓存线。我们真的没有 缓
ints
的3个方形数组1023x1023、1024x1024、1025x1025,并观察到1024x1024情况下访问第一列的速度较慢
作者解释(背景信息,CPU为Intel,具有32KB内存的一级缓存,8路关联):
当N=1024时,这个差值正好是4096字节;它等于
临界跨步值。这意味着从第一个
列匹配一级缓存的相同八条缓存线。我们真的没有
缓存的性能优势在于我们无法使用它
高效:我们只有512字节(8条缓存线*64字节缓存
行大小)而不是原来的32 KB。当我们迭代
循环中的第一列,对应的元素从中相互弹出
缓存。当N=1023和N=1025时,我们对
关键步幅:所有元素都可以保存在缓存中,这
它的效率要高得多
因此,看起来惩罚来自于某种程度上收缩缓存,仅仅因为主内存无法映射到完全缓存
这让我感到奇怪,在阅读了wiki页面后,我会说性能的损失来自于解决地址冲突。由于每一行都可能映射到同一缓存线中,因此冲突一个接一个,CPU必须解决这些问题—这需要时间
因此,我的问题是,性能问题的真正本质是什么。缓存的可访问内存大小较低,或者整个缓存可用,但CPU在解决与映射的冲突方面花费了更多时间。或者还有其他原因?缓存是两个其他层之间的一个层。在您的情况下,在CPU和RAM之间。在最好的情况下,CPU很少需要等待从RAM中获取某些内容。在最坏的情况下,CPU通常必须等待 这个例子遇到了一个坏情况。对于整个列,从RAM请求的所有字都位于缓存中的同一个单元中(或相同的2个单元,如果使用双向关联缓存,等等) 同时,CPU并不在意——它向缓存请求内存中的一个字;缓存要么拥有它(快速访问),要么需要进入RAM(慢速访问)才能获取它。RAM也不在乎——无论请求何时到来,它都会响应 回到1024。查看内存中该阵列的布局。该行的单元格是RAM的连续字;当一行完成时,下一行开始。稍加考虑,您可以看到,当N=4或8(或任何单元格大小)时,列中的连续单元格的地址相差1024*N。这是2的幂 现在让我们看看缓存的相对简单的体系结构。(它是“微不足道的”,因为它需要快速且易于实现。)它只需从地址中取出几位,就可以在缓存的“内存”中形成地址 由于2的幂,这些位总是相同的——因此访问相同的插槽。(我遗漏了一些细节,比如现在需要很多位,因此缓存的大小、双向等) 当上面的进程(CPU)在某个项目(字)被其他需要空间的项目从缓存中冲出之前多次获取该项目(字)时,缓存非常有用 注意:这是指CPU->RAM缓存,而不是磁盘控制器缓存、数据库缓存、网站页面缓存等;他们使用更复杂的算法(通常是散列),而不是“从地址中选取一些位” 回到你的问题上来 因此,看起来惩罚来自于某种程度上收缩缓存,仅仅因为主内存无法映射到完全缓存 这句话在概念上有问题
- 主内存未“映射到缓存”;查看虚拟地址与真实地址
- 当缓存没有所需的字时,将受到惩罚
- “收缩缓存”--缓存的大小是固定的,取决于所涉及的硬件
回到你的1K*1K数组,比如说,4字节的数字。加起来是4MB,加上或减(对于10231025)。如果您有8MB的缓存,那么最终将加载整个阵列,并且由于在缓存中,对阵列的进一步操作将更快。但是如果你有,比如说,1MB的缓存,数组中的一些会进入缓存,然后被抛出——重复。这可能不会比没有缓存好多少。所有访问的项目都映射到同一组缓存。该项可以进入集合中的8条缓存线中的任何一条,但由于64条缓存线中只有一条被使用,因此只有8条缓存线可以保存来自阵列的数据(而不是64*8=512条缓存线)。这就好像缓存是由512字节组成的。它叫。记住:缓存不是完全关联的,相同的地址总是映射到相同的集合。不过,也请参见感谢您的回答(不要误解我),因为一级缓存是32KB,您的回答没有解释为什么1024x1024比其他缓存慢。毕竟,这些数组中的任何一个都完全适合缓存。所以这里的关键点是缓存的关联性,因为它是速度差异的根源。@greenoldman-缓存中的“单词”有多宽?16字节将包括来自4列的整数。它是N向关联的吗?问题有可能来自二级缓存吗?(其他细节将有助于给出答案。)至于单词的宽度,我不知道。本例中的L1为8路关联