首页 > 解决方案 > 主存访问时间差异的原因

问题描述

我用一个简单的 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 -> 主内存 -> 磁盘。

提前致谢。

标签: cachingmemoryramflushcpu-cache

解决方案


推荐阅读