Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 缓存关联性如何影响性能_Performance_Caching_Cpu_Cpu Cache - Fatal编程技术网

Performance 缓存关联性如何影响性能

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字节;它等于 临界跨步值。这意味着从第一个 列匹配一级缓存的相同八条缓存线。我们真的没有 缓

我正在阅读Andrey Akinshin的“Pro.NET基准测试”,有一件事让我感到困惑(第536页)——解释如何影响性能。在一次测试中,作者使用了
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缓存,而不是磁盘控制器缓存、数据库缓存、网站页面缓存等;他们使用更复杂的算法(通常是散列),而不是“从地址中选取一些位”

回到你的问题上来

因此,看起来惩罚来自于某种程度上收缩缓存,仅仅因为主内存无法映射到完全缓存

这句话在概念上有问题

  • 主内存未“映射到缓存”;查看虚拟地址与真实地址
  • 当缓存没有所需的字时,将受到惩罚
  • “收缩缓存”--缓存的大小是固定的,取决于所涉及的硬件
定义:在此上下文中,“字”是RAM中连续的字节字符串。它总是(?)一个2字节的幂次方,并且位于reall地址空间中的某个倍数。缓存的“字”取决于CPU的年份、缓存的级别等。今天可能可以找到4、8、16字节的字。再一次,2的幂和定位在多个。。。这些都是简单的优化


回到你的1K*1K数组,比如说,4字节的数字。加起来是4MB,加上或减(对于10231025)。如果您有8MB的缓存,那么最终将加载整个阵列,并且由于在缓存中,对阵列的进一步操作将更快。但是如果你有,比如说,1MB的缓存,数组中的一些会进入缓存,然后被抛出——重复。这可能不会比没有缓存好多少。

所有访问的项目都映射到同一组缓存。该项可以进入集合中的8条缓存线中的任何一条,但由于64条缓存线中只有一条被使用,因此只有8条缓存线可以保存来自阵列的数据(而不是64*8=512条缓存线)。这就好像缓存是由512字节组成的。它叫。记住:缓存不是完全关联的,相同的地址总是映射到相同的集合。不过,也请参见感谢您的回答(不要误解我),因为一级缓存是32KB,您的回答没有解释为什么1024x1024比其他缓存慢。毕竟,这些数组中的任何一个都完全适合缓存。所以这里的关键点是缓存的关联性,因为它是速度差异的根源。@greenoldman-缓存中的“单词”有多宽?16字节将包括来自4列的整数。它是N向关联的吗?问题有可能来自二级缓存吗?(其他细节将有助于给出答案。)至于单词的宽度,我不知道。本例中的L1为8路关联