首页 > 代码库 > gem5验证数组的缓存优化

gem5验证数组的缓存优化

陆续写些关于新书《自己动手写CPU》的博客,本篇主要是讲解 gem5验证数组的缓存优化


软件优化是提高cache命中率的十分有效的手段,cache的基本原理是利用程序局部性,而软件优化可以通过提高程序局部性,从而提高cache命中率。举一个例子如下:

程序A:

#include <stdio.h>

int main()
{
    int i=0,j=0;
    long count=0;
    long temp[51200][8];      
 
    for(i=0;i<51200;i++)
       for(j=0;j<8;j++)
           {
           temp[i][j]=i*j;   //  大约51200 次DCache缺失
           }
 
}
在C语言中,二维数组在内存中是按照行的次序在按照列的次序存放,也就是说,二维数组中同一行的数据在内存中是挨着的,但同一列的数据在内存中是分散的。

假设数据cache的line size是64,long类型是8个字节,那么在程序A中,temp[i][0]-temp[i][7]刚好是64字节,占用数据cache的一个line,所以在写temp[i][0]将发生一次cache缺失,在写temp[i][1]-temp[i][7]的时候,不会发生数据缺失,所以,一共发生51200次缺失。

程序B:

#include <stdio.h>

int main()
{

    int i=0,j=0;
    long count=0;
    long temp[51200][8];      

    for(i=0;i<8;i++)
       for(j=0;j<51200;j++)
           {
           temp[j][i]=i*j;   // 大约8*51200 次DCache缺失
           }
}
仍然假设数据cache的line size是64,long类型是8个字节,那么在程序B中,是先按照列的次序访问,在按照行的次序访问,所以每次访问都会发生数据cache缺失,一共发生8*51200=409600次缺失。

下面我们通过gem5仿真验证上述分析是否正确。

还是以我的开发环境为例,gem5安装在/root/gem5/gem5-stable-50ff05095970/路径下,修改tests/test-progs/hello/src目录下的hello.c,如下:

#include <stdio.h>

int main()
{

    int i=0,j=0;
    long count=0;
    long temp[51200][8];      

}
使用如下命令编译(需要在/root/gem5/gem5-stable-50ff05095970/tests/test-progs/hello/src目录下执行下面的命令):

gcc --static hello.c -o hello
然后使用前几次编译得到的X86对应的gem5.opt运行hello,并且选择CPU模型是Timing,也就是顺序流水线模型,命令如下(需要在/root/gem5/gem5-stable-50ff05095970/路径下执行下面的命令):
./build/X86/gem5.opt ./configs/example/se.py --cpu-type=timing --caches -c ./tests/test-progs/hello/src/hello
得到的统计结果在m5out/stats.txt中,找到其中的如下数据(分别是执行时间和数据cache写操作的缺失数):

sim_seconds                                  0.000030                       # Number of seconds simulated......system.cpu.dcache.WriteReq_misses::cpu.data           90

修改hello.c的代码为程序A,然后编译,并使用gem5.opt运行,再次打开stat.txt得到运行时间、数据cache的缺失数如下:

sim_seconds                                  0.013802......system.cpu.dcache.WriteReq_misses::cpu.data        51290
可见数据cache的缺失数增加了51200,符合我们前期的分析。

修改hello.c的代码为程序B,然后编译,并使用gem5.opt运行,再次打开stat.txt得到运行时间、数据cache的缺失数如下:

sim_seconds                                  0.031548......system.cpu.dcache.WriteReq_misses::cpu.data       409688

可见数据cache的缺失数增加了409588,接近409600,基本符合预期。通过实验可以更加深刻的了解到程序优化对缓存使用的影响。

gem5验证数组的缓存优化