caching - 主存访问时间差异的原因
问题描述
我用一个简单的 c 程序进行了一些实验,以估计由于缓存未命中而从主内存中获取值的成本。
我的第一个实验涉及在 clflush 指令的帮助下使全局变量的相应缓存行无效后访问全局变量。BEGIN、CLOSE 和 GET_TIME 是我为使用时钟周期数作为度量的代码时序片段定义的宏。
int global_var = 0; // Global variable
int main() {
for(int i = 0; i < rounds + warmup; ++i) {
clflush(&global_var);
BEGIN
int x = global_var;
CLOSE
access_times[i] = GET_TIME;
}
return 0;
}
我的实验表明,当它不在 CPU 缓存中时,访问“global_var”大约需要 200 个时钟周期,这与我从其他来源听到的访问时间相对应。然而,在我的实验中,一些主存访问需要的时间远远超过 200 个时钟周期,介于 500-1000 个时钟周期之间,这让我想到了我的第一个问题。
某些主内存访问比绝大多数访问慢得多的可能原因是什么?
我的第二个实验涉及访问相同的全局变量,但不是在 clflush 指令的帮助下刷新缓存行,而是通过读取至少与我的 L3 一样大的内存块来刷新整个 CPU 缓存(L1、L2 和 L3)缓存(在我的情况下为 4MB)。写入块的大小保存在下面代码中的 BLOCK_SIZE 常量中。
int global_var = 0; // Global variable
int main() {
char *dummy = malloc(BLOCK_SIZE);
for(int i = 0; i < rounds + warmup; ++i) {
memset_s(dummy, 1, BLOCK_SIZE);
BEGIN
int x = global_var;
CLOSE
access_times[i] = GET_TIME;
}
return 0;
}
这个实验的结果表明,如果我写一个比 L3 缓存大一点的块,大多数主存访问大约需要 200 个时钟周期。但是,随着我增加写入块的大小,访问时间会变大。例如,如果我写一个大小为 L3_SIZE * 2 的块,那么从主存储器获取“global_var”的平均时间大约是 500 个时钟周期。
我的第二个问题是,当我通过写入更大的块来清除 CPU 缓存时,为什么主内存访问时间会变长?我系统的内存/缓存层次结构是:L1 -> L2 -> L3 -> 主内存 -> 磁盘。
提前致谢。
解决方案
推荐阅读
- django - 如何将包含经度/纬度的列表更改为包含纬度/经度的列表 - Django?
- css - 如何让我的 CSS 过渡只适用于一个元素?
- javascript - 如何使用 Typescript 键入数组的值
- regex - 正则表达式用单个字符替换多次出现的字符
- python-3.x - Python。简单的计算器。从字符串中抓取算术运算符
- python - pytest repeat - 获取当前迭代次数
- r - 如何用另一张纸上的实际基因名称信息替换 DESeq2 rlogTransformation 矩阵中的行名?
- python - 2021 年 9 月 13 日 Google Drive API 更新如何影响使用 pydrive 进行身份验证
- c# - 在 DataGridView 中搜索,如何在过滤后的行中进行过滤
- android - 如何在 android 上以低延迟播放 RTSP 流?