我试图了解处理器中如何使用各种缓存。假设我正在递增67字节数组的每个值。让我们假设一个32位的Linux操作系统。
让我们假设缓存行是64字节。现在,如果我有以下代码 -
<?php
require_once 'jsonRPCClient.php';
$bitcoin = new jsonRPCClient('http://user:password@127.0.0.1:8332/');
echo "<pre>\n";
print_r($bitcoin->getinfo());
echo "</pre>";
?>
有人可以解释处理器缓存如何用于此功能吗?如果我正确理解了缓存行概念,那么每次处理器想要将一个字节复制到L1时,是否会复制64字节的数据?
编译器如何优化此代码以有效地使用缓存?
如果问题完全是废话,请告诉我如何。
答案 0 :(得分:0)
确切的答案将依赖于太多的参数,例如系统实现等,但我会尝试给出我的直觉,因为它已经过了一个月,而你什么都没有。
您可能已经知道这一点,但请注意a
的大小为67字节:
#include <stdio.h>
int main(void)
{
unsigned char a[67] = {0};
printf("%zu\n", sizeof(a)); // prints 67
return 0;
}
我们的缓存是64字节,因此我们假设当a
完全为空时它可以容纳64个单元格。
您的代码循环开始执行,i
是一个变量,让我们假设它的不将被缓存,以便我们制作回答更简单。
您的代码尝试访问a[i]
,因此我们在缓存中查找,但在缓存为空时,即始终在开始时看不到任何内容(称为冷启动)该程序,强制缓存未命中。)
a
的前64个字节将被复制到缓存中,假设操作系统将整个数组视为一个。
你做了添加,但你更新了a[i]
,i = 0,所以如果你再次访问a[i]
,它的位将被标记为脏,缓存查找将导致错过
接下来循环,我们想要a[1]
,我们检查缓存,欢呼!它已经存在,所以我们有一个缓存命中。依此类推,直到我们请求a[64]
,这不在缓存中,因为整个数组都不适合。
操作系统会获取a[64]
,现在问题是谁将成为替代受害者,因为它可能还想获取a[65]
和a[66]
。
它选择负责的替换策略的受害者,当我们要求a[65]
时,假设它与a[64]
一起被提取,我们将有一个缓存命中。< / p>
这是一个非常近似的,在某种程度上不准确的概述会发生什么,但这里的重点是给你直觉,希望它有所帮助! :)