【深大计算机系统(2)】实验五 Cache实验 实验报告 附实验代码、常用指令、实验数据

目录

一、实验目的:

二、实验环境:

三、实验内容与步骤:

四、实验过程及内容:

1. 分析Cache访存模式对系统性能的影响:

2. 测量分析出Cache 的层次结构、容量以及L1 Cache行有多少?

3. 尝试测量你的x86机器TLB有多大?(选作)

五、实验总结与体会

尾注

附录:

实验代码:

1. 矩阵运算代码:

2. mountain绘图代码(matlab):

3. 测量TLB代码:

常用虚拟机指令:


写在前面:

上交的实验报告需要包含账户的姓名全拼以及学号,本报告的相应部分已经打码处理,请在自己的环境中完成实验!

一、实验目的:

1.    加强对Cache工作原理的理解;

2.    体验程序中访存模式变化是如何影响cahce效率进而影响程序性能的过程;

3.    学习在X86真实机器上通过调整程序访存模式来探测多级cache结构以及TLB的大小。

二、实验环境:

X86真实机器

三、实验内容与步骤:

1. 分析Cache访存模式对系统性能的影响

        (1)给出一个矩阵乘法的普通代码A,设法优化该代码,从而提高性能。

        (2)改变矩阵大小,记录相关数据,并分析原因。

2. 编写代码来测量x86机器上(非虚拟机)的Cache 层次结构和容量

        (1)设计一个方案,用于测量x86机器上的Cache层次结构,并设计出相应的代码;

        (2)运行你的代码获得相应的测试数据;

        (3)根据测试数据来详细分析你所用的x86机器有几级Cache,各自容量是多大?

        (4)根据测试数据来详细分析L1 Cache行有多少?

3. 尝试测量你的x86机器TLB有多大?(选作)

四、实验过程及内容:

准备工作:

        首先在虚拟机桌面上新建一个实验五的文件夹experiment_5用于保存本实验所用的所有文件。下载main_a.c文件后使用指令gcc -o main_a main_a.c 进行编译,发现没有错误。

图:编译main_a.c

        图中,第一次编译错误是由于“-o”的命令出错,具体原因是ppt中给出的指令使用的符号并不是标准的“-”,而是“–”,导致机器无法识别。修改后即可正确编译并生成可运行文件。

接下来即可开始实验:

1. 分析Cache访存模式对系统性能的影响:

        使用指令./main_a x,以x*x为矩阵的大小运行程序./main_a,并记录运行时间,填入表中(单位为秒)。

        接下来阅读源代码,并尝试优化:

        阅读代码可以得知,程序的主要功能是实现两个矩阵的相乘运算,将大小为x*x的矩阵a,b相乘的结果保存在矩阵c中。但此代码的空间局部性较差,常常访问距离当前访问地址较远的地址,具体而言,在对c某个位置的计算时,对矩阵b的访问中,程序每次访问的地址将会增加size,此时如果size较大,访问的空间将会距离较大,因此空间局部性差。

        优化方法:将原始的整块矩阵相乘拆分为一个个小矩阵块相乘,从而提高了空间局部性,提高运行效率。计算部分的代码如图:

图:核心代码

        其中,BLOCK_SIZE即为矩阵块的大小。

        接下来,由于我们并不能直接确定块的合适大小,因此我尝试将此参数进行多次调整,找到一个较优的值:

图:参数调整过程

        图中第二个参数即为BLOCK_SIZE的值,如图可以发现,512为一个较优的参数值。

        接下来固定参数,进行实验,并统计实验结果:

图:实验过程

        最终实验结果如表:

        如表,代码的优化带来了显著的效果。

2. 测量分析出Cache 的层次结构、容量以及L1 Cache行有多少?

        首先需要对mountain文件进行解压:tar-xvf mountain.tar

图:解压成功

        接着使用make生成可执行文件,并将其运行:

图:运行结果

        将运行结果保存到本地,并使用matlab画图:

图:数据山

        图中能明显地观察到读取速度的分层现象。

        根据上述的实验结果可以分析出:随着读取内容的增多,读取速度三次下降分别出现在:512KB~1024KB、4MB~8MB、8MB~16MB,说明本电脑共存在三级缓存,且这三段速度下降分别对应了这三段缓存的切换过程。其中L1缓存的容量可能约为768KB、L2缓存为6MB、L3缓存为12MB。

        而随着步长的变化,读取速度也会出现对应的突变:这样的突变是由于数据是按块加载到缓存中的,较大的步长可能会导致两次连续的访问必然不可能出现在同一块中,从而降低了读取速度。本实验中,测得步长达到40步左右时会出现突变,L1缓存的行约为512KB/40*8B=1638行

        打开任务管理器验证实验结果:

图:三个缓存真实大小

        如图所示,三个缓存的真实容量与实验结果相吻合。

3. 尝试测量你的x86机器TLB有多大?(选作)

        TLB的定义:TLB(Translation Lookaside Buffer)是位于CPU内部的一种专用缓存,用于加速虚拟地址到物理地址转换的硬件缓存。

        当CPU执行程序时,会生成虚拟地址来访问内存,CPU首先会调用TLB,如果TLB中存在该虚拟地址对应的物理地址,则直接使用TLB中的物理地址进行内存访问。反之需要通过页表来进行地址转换。

        因此我编写了一个程序:首先创建一个相当大的数组(此处为256MB),此数组的大小会远超TLB的大小。接着使用不同步长进行数组的遍历:首先为1,然后每次乘以2。并统计每种步长对应的访问时间。如果步长*单位长度(此处取的是4KB)小于TLB,则地址可能可以直接在TLB中找到,从而访问较快;反之访问较慢。这样一来,只需要找到访问时间突变对应的步长,即可计算出TLB的大小。

        接下来运行程序,结果如图。将总访问时间乘以对应的步长可以得到访问相同空间所需的时间,可以看到,在步长为8~16的实验中,相对时间出现了较大的突变。因此,计算出来的TLB大小为32KB~64KB。

图:运行结果

五、实验总结与体会

实验总结:

        本次实验我利用程序的局部性的知识,优化了矩阵乘法的代码,将矩阵乘法的运行效率显著提高,最大加速比约为173%。接下来运行了mountain程序,得到了不同访问大小、不同步长时的读取速度,并将其绘图展示。根据此实验的结果,我测得了CPU具有三级缓存,以及它们对应的大小分别为:768KB、6MB、12MB。我在任务管理器中直接查看了三级缓存对应的大小,验证了上述实验结果的正确性。最后,我学习了TLB的相关知识,编写代码测量了程序以不同步长访问同一数组所需要的时间,以此估算出TLB的大小约为48KB

实验体会:

        本次实验中数据山的画图部分最为困难,需要学习matlab绘图函数,将实验结果可视化。除此之外,TLB的测量部分也较为困难,要完成此任务,需要首先查阅资料,学习TLB的相关知识,再利用其特性,使用不同步长访问数组的方式,完成TLB大小的估算。

尾注

        如有疑问欢迎讨论,如有好的建议与意见欢迎提出,如有发现错误则恳请指正!

附录:

实验代码:
1. 矩阵运算代码:
#include <sys/time.h> 
#include <unistd.h> 
#include <stdlib.h>
#include <stdio.h> 

int main(int argc, char* argv[])
{
    float* a, * b, * c, temp;
    long int i, j, k, size, m;
    struct timeval time1, time2;

    if (argc < 2) {
        printf("\n\tUsage:%s <Row of square matrix>\n", argv[0]);
        exit(-1);
    } //if

    size = atoi(argv[1]);
    int BLOCK_SIZE = atoi(argv[2]);
    m = size * size;

    a = (float*)malloc(sizeof(float) * m);
    b = (float*)malloc(sizeof(float) * m);
    c = (float*)malloc(sizeof(float) * m);


    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            a[i * size + j] = (float)(rand() % 1000 / 100.0);
            b[i * size + j] = (float)(rand() % 1000 / 100.0);
            c[i * size + j] = 0;
        }
    }

    gettimeofday(&time1, NULL);

    long int ii, jj, kk;
    for (ii = 0; ii < size; ii += BLOCK_SIZE)
        for (jj = 0; jj < size; jj += BLOCK_SIZE)
            for (kk = 0; kk < size; kk += BLOCK_SIZE)
                for (i = ii; i < ii + BLOCK_SIZE && i < size; i++)
                    for (j = jj; j < jj + BLOCK_SIZE && j < size; j++)
                        for (k = kk; k < kk + BLOCK_SIZE && k < size; k++)
                            c[i * size + j] += a[i * size + k] * b[k * size + j];

    gettimeofday(&time2, NULL);

    time2.tv_sec -= time1.tv_sec;
    time2.tv_usec -= time1.tv_usec;
    if (time2.tv_usec < 0L) {
        time2.tv_usec += 1000000L;
        time2.tv_sec -= 1;
    }

    printf("Executiontime=%ld.%06ld seconds\n", time2.tv_sec, time2.tv_usec);

    return(0);
}//main
2. mountain绘图代码(matlab):
% 数据准备
sizes = [2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768]
strides = 1:64; % 列对应的stride

% 吞吐量数据
data = [
    8519.7	8519.7	9727.3	10223.7	10208.7	8511.4	7288.4	8519.7	11331.9	20367.5	18570.3	16972.9	15675.0	14576.7	13578.3	12779.6	11980.9	11282.0	10682.9	10183.7	9684.5	9285.2	8885.8	8486.4	8087.1	7787.6	7488.0	7288.4	6988.8	6789.2	6589.5	6389.8	6190.1	5990.4	5790.8	5591.1	5491.2	5291.6	5191.7	5091.9	4892.2	4792.3	4692.5	4592.7	4492.8	4393.0	4293.1	4193.3	4093.5	3993.6	3993.6	3893.8	3793.9	3694.1	3694.1	3594.3	3494.4	3494.4	3394.6	3394.6	3294.7	3294.7	3194.9	3194.9;
    8345.9	8519.7	9734.5	10223.7	11681.3	11348.5	11681.3	12779.6	11356.9	10208.7	9285.2	11348.5	10483.3	9717.8	13628.2	12779.6	11980.9	11331.9	21465.7	20367.5	9734.5	18570.3	17771.6	8486.4	16274.0	7837.5	7538.0	14576.7	14077.5	6789.2	13179.0	12779.6	12380.2	11980.9	11681.3	11282.0	5491.2	10682.9	10483.3	5091.9	9884.2	9684.5	9484.9	9285.2	9085.5	8885.8	8686.1	8486.4	8286.8	8087.1	7987.2	7787.6	7687.7	7488.0	7388.2	7288.4	7088.7	6988.8	6889.0	6789.2	6689.3	6589.5	6489.6	6389.8;
    8431.9	8701.0	8792.4	9294.2	9085.5	9734.5	9734.5	10223.7	10095.0	11681.3	12380.2	11348.5	12579.9	9734.5	10902.6	12779.6	12005.8	11356.9	10757.8	10208.7	9734.5	9285.2	11847.7	11348.5	10882.6	10483.3	15125.8	14576.7	14077.5	13628.2	13179.0	12779.6	12380.2	11980.9	23362.7	11331.9	11032.4	21465.7	10483.3	10183.7	9934.1	9734.5	9484.9	18570.3	18171.0	17771.6	8686.1	16972.9	8336.7	16274.0	7987.2	15675.0	15375.4	7538.0	14776.4	14576.7	7138.6	14077.5	13778.0	13578.3	13378.6	6589.5	12979.3	6389.8;
    8519.7	8609.4	8654.4	8701.0	8839.9	9085.5	8985.7	9294.2	9563.7	9085.5	9291.4	9734.5	9676.9	9734.5	9911.4	10223.7	9614.6	10095.0	10757.8	10221.2	12979.3	12380.2	11847.7	13618.3	13079.1	12579.9	12100.7	11681.3	14077.5	10902.6	10543.2	12779.6	12380.2	16007.8	9345.1	7571.2	8825.9	8606.3	8386.6	8167.0	9959.1	9734.5	12679.8	12380.2	9085.5	11847.7	11581.5	11348.5	16673.4	10882.6	10682.9	15724.9	10283.6	10083.9	9884.2	9717.8	14327.1	14077.5	13827.9	13628.2	13378.6	13179.0	12979.3	12779.6;
    8453.7	8519.7	8453.2	8609.4	8608.6	8654.4	8654.7	8701.0	8863.9	8839.9	9009.9	8792.4	8985.7	8985.7	9085.5	8890.2	9161.6	9085.5	9059.2	9085.5	9734.5	9291.4	9478.2	9734.5	10060.9	9676.9	9315.9	9734.5	9393.3	9911.4	9593.8	9294.2	9904.2	12018.3	11681.3	10095.0	11044.9	10757.8	11980.9	10221.2	11396.1	11125.1	12679.8	10611.6	10383.4	10155.2	11598.1	9727.3	11115.6	10899.3	10682.9	10483.3	12340.3	12100.7	11881.0	11681.3	14327.1	11262.0	11082.3	13628.2	13403.6	13179.0	12979.3	10223.7;
    8442.8	8453.7	8486.4	8519.7	8553.0	8586.3	8575.3	8609.4	8552.2	8608.6	8619.6	8654.4	8677.5	8818.0	8724.1	8701.0	8747.4	8863.9	8829.5	8839.9	8652.8	9009.9	8888.9	9085.5	9023.5	8985.7	8974.6	8985.7	9021.6	9085.5	9176.7	9294.2	9008.3	9161.6	9345.1	9563.7	9306.2	9562.5	9318.5	9085.5	9385.0	9734.5	9509.8	9291.4	9691.2	9478.2	9278.5	9734.5	9534.8	9342.2	9163.9	9676.9	9492.5	10092.2	9909.2	9734.5	10428.8	10247.3	10074.8	9911.4	9748.1	9593.8	10383.4	6815.8;
    8426.5	8442.8	8486.4	8475.6	8497.5	8519.6	8536.1	8519.7	8552.8	8553.0	8558.3	8519.2	8530.4	8575.3	8637.7	8609.4	8649.1	8654.0	8608.8	8608.6	8654.2	8619.6	8619.6	8654.4	8722.7	8677.5	8654.0	8654.7	8676.5	8724.1	8794.3	8701.0	8810.4	8747.4	8900.1	8863.9	8840.9	8829.5	8828.0	8839.9	8863.6	8900.1	8950.4	8744.9	8810.2	8888.9	8698.6	9085.5	8899.1	9023.5	9163.9	8985.7	9144.7	8974.6	8811.9	8985.7	9181.3	9021.6	9239.4	9085.5	8935.7	9176.7	9029.1	6196.2;
    8442.8	8464.6	8470.1	8475.6	8470.0	8470.0	8459.1	8475.6	8478.3	8497.5	8497.5	8486.4	8458.8	8497.3	8511.3	8519.7	8505.8	8502.8	8503.1	8497.5	8536.4	8497.1	8555.5	8519.2	8510.8	8530.4	8578.3	8575.3	8513.8	8553.0	8527.8	8519.7	8619.9	8553.0	8594.3	8552.2	8625.3	8502.5	8602.9	8608.6	8625.4	8654.2	8572.2	8619.6	8680.2	8619.6	8566.3	8519.2	8613.7	8579.7	8553.0	8677.5	8663.4	8654.0	8651.6	8654.7	8663.5	8676.5	8697.9	8724.1	8580.3	8614.8	8654.9	6103.7;
    8434.6	8423.8	8425.1	8394.0	8395.3	8380.6	8392.7	8345.9	8332.5	8321.8	8204.5	8261.4	8085.3	8006.3	7754.7	8158.5	8277.1	8261.5	8175.1	8282.3	8281.1	8261.5	8275.9	8261.4	8308.6	8284.7	8285.1	8271.7	8279.4	8308.6	8277.0	8138.2	8304.5	8321.8	8308.4	8261.2	8321.4	8348.5	8336.4	8335.1	8290.0	8308.7	8337.4	8318.9	8308.2	8366.8	8373.8	8324.1	8345.3	8308.2	8344.4	8388.3	8369.7	8356.5	8134.0	8199.2	8199.4	8204.2	8214.7	8230.3	8250.3	8196.6	8145.8	5242.9;
    8401.4	8412.9	8417.0	8412.9	8381.9	8368.5	8378.6	8324.6	8326.6	8328.5	8348.5	8269.4	8159.1	7646.1	7913.1	7190.3	7746.1	7796.4	7815.6	7991.5	8172.5	8247.1	8413.6	8372.4	8459.8	8371.0	8447.5	8440.0	8434.4	8388.5	8485.2	8220.0	8482.4	8344.4	8473.4	8478.3	8496.6	8425.1	8494.7	8361.7	8455.0	8478.3	8483.0	8497.5	8490.5	8492.0	8501.7	8486.4	8511.9	8476.7	8482.3	8494.5	8514.0	8503.1	8497.6	8458.9	8463.9	8473.8	8489.8	8511.3	8495.8	8527.8	8478.3	4972.0;
    8426.8	8235.6	8431.2	8418.3	8395.4	8370.5	8376.2	8348.5	8329.6	8285.7	8330.2	8199.4	8188.2	8421.0	8393.7	7226.0	8384.2	8386.6	7041.5	7002.7	7246.0	7662.9	8374.9	8412.9	8408.9	8371.1	8438.3	8449.6	8454.3	8439.4	8442.8	8345.9	8392.7	8389.9	8437.6	8441.4	8371.1	8425.1	8388.6	8348.4	11959.8	12041.6	11993.2	12016.7	12054.1	12009.8	12007.8	11918.1	12070.8	12033.4	12074.8	11877.5	12044.2	12041.6	12047.2	12061.1	12004.4	12073.4	12070.5	12074.8	12086.0	12061.1	12085.4	7050.8;
    8423.1	8273.0	8208.6	8158.5	8031.5	7905.0	7783.4	7945.5	8012.6	8056.2	7997.7	7791.2	7312.7	7014.9	6871.1	6369.6	6723.0	6725.8	6612.7	6676.7	6845.5	7326.6	8242.2	8429.1	8408.9	8384.3	8415.4	8369.2	8424.8	8353.5	8069.6	7573.1	8392.7	8384.2	8408.0	8410.9	8408.5	8405.8	8401.8	8361.8	8392.5	8399.7	8337.8	8400.1	8398.7	8398.0	8397.5	7234.0	8403.3	8408.9	8361.5	8397.3	8405.4	8438.3	8357.7	8440.0	8320.1	8444.4	8399.5	8388.6	8382.1	8432.2	8371.5	4433.0;
    11865.5	11700.2	8081.0	8042.6	8051.6	7968.7	7914.7	7873.2	7690.8	7553.4	7405.0	6735.5	6465.8	6240.7	6071.6	6070.4	6352.0	6411.6	6216.3	6193.8	6500.7	9538.8	9767.7	9849.5	9744.3	9805.9	6837.0	6802.7	6793.7	6727.1	6724.0	6252.4	6607.5	6528.7	6462.1	6354.7	6305.2	6333.3	6340.4	6379.7	6291.2	6459.7	6413.3	6432.8	6546.5	6467.9	6646.6	6839.8	6614.7	6618.1	6547.8	6582.0	6578.8	6608.3	6515.9	6568.2	6484.3	6599.7	6481.8	5850.3	6014.0	6022.5	5871.9	4141.2;
    8329.1	10210.8	6729.8	5982.7	5734.9	5447.6	5189.1	4880.2	4736.1	5329.8	4473.7	4295.4	4151.9	4001.4	3915.2	4320.7	4986.9	5222.4	5770.8	6041.0	6555.8	6941.9	7086.5	7039.9	6985.2	6872.7	6995.0	6952.9	6752.4	6687.6	6680.7	3381.3	6545.3	6474.7	6477.0	6417.8	6469.2	6541.0	6549.2	6628.1	6600.1	6545.5	6320.7	6335.4	6320.8	6323.0	6240.5	6461.2	6290.9	6226.9	6289.6	6342.3	6332.3	6235.0	6065.6	6261.6	6129.9	6210.8	6212.4	6162.8	6133.5	6100.0	5984.3	2975.5;
    10210.0	7710.4	7007.7	6004.9	5391.6	4882.8	4340.9	3966.4	3602.9	3653.0	3095.2	2993.3	2985.3	2871.8	2834.5	2106.3	3583.1	3598.9	3562.2	3902.7	4139.8	4420.6	4835.1	5753.3	5478.3	7030.2	5832.4	6073.7	6225.8	6158.7	6317.2	1974.8	6242.3	6264.8	6378.2	6286.0	6374.0	6475.7	6691.1	6860.4	6722.9	6692.2	6630.6	9157.9	6628.7	6481.1	6615.8	5219.8	6508.9	6634.5	6662.8	6827.6	6406.8	6453.0	6144.5	6521.6	6537.7	6594.4	6507.1	6610.0	6515.5	6568.7	6328.2	1812.0;
];

% 创建网格
[X, Y] = meshgrid(strides, sizes);

% 绘制三维图
figure;
surf(X, Y, data);

% 设置颜色映射
colormap jet;
colorbar;

% 添加标签
xlabel('Stride');
ylabel('Size (KB)');
set(gca, 'YDir', 'reverse')
zlabel('Throughput (KB/sec)');
title('Memory Mountain');

% 调整视角
view(45, 30);
3. 测量TLB代码:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define ARRAY_SIZE (256 * 1024 * 1024) // 256MB
#define PAGE_SIZE 4096 // 4KB
#define NUM_TRIALS 1000 // 访问次数

void clear_cache() {
    int* dummy = (int*)malloc(ARRAY_SIZE);
    for (int i = 0; i < ARRAY_SIZE / sizeof(int); i += PAGE_SIZE / sizeof(int)) {
        dummy[i] = i;
    }
    free(dummy);
}

void measure_tlb_miss_rate() {
    int* array = (int*)malloc(ARRAY_SIZE);
    int stride, i, trial;
    LARGE_INTEGER start, end, frequency;
    double elapsed_time;

    // 获取高精度计时器的频率
    QueryPerformanceFrequency(&frequency);

    printf("Stride (pages)\tTime (ms)\n");

    for (stride = 1; stride <= 1024; stride *= 2) {
        elapsed_time = 0.0;

        for (trial = 0; trial < NUM_TRIALS; trial++) {
            // 清空缓存
            clear_cache();

            // 开始计时
            QueryPerformanceCounter(&start);

            // 访问数组
            for (i = 0; i < ARRAY_SIZE / sizeof(int); i += stride * PAGE_SIZE / sizeof(int)) {
                array[i] = i;
            }

            // 结束计时
            QueryPerformanceCounter(&end);

            // 累加时间
            elapsed_time += (double)(end.QuadPart - start.QuadPart) * 1000.0 / frequency.QuadPart;
        }

        // 计算平均时间
        elapsed_time /= NUM_TRIALS;

        printf("%d\t\t%f\n", stride, elapsed_time);
    }

    free(array);
}

int main() {
    measure_tlb_miss_rate();
    return 0;
}
常用虚拟机指令:
实验五:/*
	进入实验五文件夹(需要先创建):cd ~/Desktop/experiment_5
	编译main_a.c:gcc -o main_a main_a.c
	以不同大小运行main_a(此处为100):./main_a 100
	编译main_a_better.c:gcc -o main_a_better main_a_better.c
	以不同矩阵大小、块大小运行优化的main_a(此处为1500、16):
	./main_a_better 1500 512
	解压mountain:tar-xvf mountain.tar
*/

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值