美文网首页
Cache Lab Implementation and Blo

Cache Lab Implementation and Blo

作者: 苺一語 | 来源:发表于2019-04-30 16:05 被阅读0次

    Aakash Sabharwal
    J 部分
    2013 年 10 月 7 日

    欢迎来到指针的世界!

    译注:这个漫画我也看不懂

    课程时间安排

    Cache Lab
    • 截止:周四
    • 开始:现在(如果你还没开始的话)
    马上就考试!
    • 开始做练习题
      10 月 16 日 周三 —— 10 月 19 日 周六
    • 10 天

    大纲

    • 时间表
    • 内存组织
    • 缓存
        - 不同类型的地区(locality,我也不知道怎么翻译合适)
        - 缓存组织
    • Cachelab
        - (a)部分:搭建缓存模拟器
        - (b)部分:高效矩阵转置

    内存层次

    内存层次

    内存层次

    • 寄存器
    • SRAM <=(我们将讨论这两者的交互)
    • DRAM <=
    • 本地副存储
    • 远程副存储

    SRAM 与 DRAM:权衡

    ➤ SRAM(缓存)

    • 更快(L1缓存:1个CPU周期)
    • 更小(千字节(L1)或兆字节(L2))
    • 更昂贵而且“吃电”

    ➤DRAM(主内存)

    • 相对较慢(数百CPU周期)
    • 更大(吉字节)
    • 更便宜

    地方

    时间地方

    • 最近被引用过的项目更有可能在未来被引用
    • 在访问内存地址 X 之后,将这些字节存储在缓存中以备后续访问

    空间地方

    • 临近地址的项目有时候会被连续地引用
    • 在访问地址 X 之后,将 X 周围的内存块存入缓存以备后续使用

    内存地址

    在 shark machine 上是64位


    内存地址
    • Block offset:b 位
    • Set index:s 位
    • Tag Bits:地址大小 - b - s

    缓存

    缓存(cache)是 2s缓存集的集合
    缓存集(cache set)是 E 个缓存行(cache line)的集合
      - E 称为 结合度(associativity)
      - 如果 E=1,这称之为“直接映射的”(direct-mapped)
    缓存行存储一个
      - 每个块有 B = 2b 字节
    总容量 = S×B×E

    虚拟缓存术语

    虚拟缓存术语

    缓存的整体概念

    缓存的整体概念

    缓存的整体概念:落空(Miss)

    Miss

    缓存的整体概念:落空的类型

    冷落空/强行落空(clod miss/compulsory miss)
    • 第一次访问块时必定落空

    译注:第一次访问时,缓存中还没有任何内容,所以必然落空;至于“冷”的意思,大概是说这时缓存就如同机器刚启动,还需要预热一下。

    冲突落空(conflict miss)
    • 当 k 级缓存足够大,但是多个数据对象映射到同一个 k 级块时,发生冲突落空
    • 例如:引用块 0,8,0,8,0,8,...每次都会落空

    译注:这是一种看起来有些奇怪的落空。造成这种落空的原因是缓存的实现形式。为了保持简洁性,k 级缓存往往会通过某种算法来决定从 k+1 级缓存取回的块存放在哪里。举一个简单的例子,假设 k级 缓存容量为 4,缓存采用取模的方法,将来自 k+1 级的 块m 放在 k 级的 块 m%4 中,那么 k+1级的块 0,4,8,12……都将映射到 k级的块 0 中。从而连续访问 0,8,0,8……时,后面的数据都会覆盖前面的数据,从而每次都落空。

    容量落空
    • 当活动状态的内存块(正在工作的集 / working set)比缓存容量还大时,发生容量落空

    译注:working set 指的是当前需要反复访问,从而应当存储在缓存中,以加快访问速度的那些块的集合;比如,我当前这段程序需要频繁访问 8 个块的数据,那么我自然想要把这 8 个块都放在缓存中,然而如果我的缓存容量只有 4 个块的大小,那么十分不幸,只能保证 4 个块的连击,另外 4 个块则会落空。

    Cache Lab

    • Part (a) 建造一个缓存模拟器
    • Part (b) 优化矩阵转置

    Part (a)

    • 缓存模拟器 并不是 缓存!
      —— 内容并不会被储存在内存中
      —— block offsets 并没用被使用 - 你地址中的 b 位并不重要
      —— 仅仅记录连击(hits),落空(misses)与驱逐(evictions)的数量

    • 你的缓存模拟器需要能够对运行时给出的不同的 s,b,E,正确运行

    • 使用 LRU - 最不近使用替换策略(Least Recently Used replacement policy)
      —— 从内存中驱逐最不近使用的块来为后续的块腾出空间
      —— 队列?时间戳?

    译注:least recently used,这个想不出好的翻译。意思就是“累积未使用时间最长的”。打个比方,手机上会有清理不常用 APP 的功能,QQ 三个月内都没有使用过(最后一次使用是三个月前),QQ音乐 两个月之内没有使用过,QQ浏览器 一个月。那么,QQ 就是“最不近使用的”,推荐你卸载掉。

    缓存模拟器:连击数

    • 缓存只是一个缓存行的 2D 数组:
      —— 结构 cache_line cache[S][E];
      —— S = 2s,代表缓存集的数量
      —— E 是结合度(associativity)

    • 每个 cache_line 包含:
      —— 有效位
      —— Tag
      —— LRU 计数器(如果你不使用队列的话)

    Cache Lab 实现:

    getopt

    • 如果函数声明丢失,getopt()在 unix 命令行上进行自动化元素解析:
      —— 通常在循环内进行调用以获取参数
      —— 返回值保存在本地变量中
      —— 当 getopt()返回 -1 时,表示没有更多选项了

    • 为了使用 getopt,你的程序需要包含头文件 unistd.h

    • 如果你不在 shark machine 上运行,那么你需要 #include<getopt.h>
      —— 更好的建议:在 Shark Machine 上运行!

    getopt

    • 在保存返回值的本地变量上使用 switch 语句
      —— 命令行的每个输入可以被分别处理
      —— “optarg” 是一个很重要的变量 - 它将指向选项参数的值

    • 思考如何处理非法输入

    getopt 示例

    int main(int argc, char** argv){
        int opt, x,y;
        /* looping over arguments */
        while(-1 != (opt = getopt(argc, argv, "x:y:"))){    
            /* determine which argument it’s processing */
            switch(opt) { 
                case 'x':
                    x = atoi(optarg);
                    break;
                case 'y':
                    y = atoi(optarg);
                    break;
                default:
                    printf("wrong argument\n");
                    break;
            }
        }
    }
    

    假设可执行程序叫做“foo”,我们通过

    ./foo -x 1 -y 3
    

    来将值 1 传给变量 x,以及 3 传给 y

    fscanf

    • fscanf()函数与 scanf()函数十分相似,只不过 fscanf()可以指定读取的流(scanf()总是从标准输入 stdin 读入)
      —— 参数:
        - 文件指针
        - 带有读取文件方式信息的格式化字符串
        - 其余为指向用于储存文件中数据的变量的指针
      —— 通常会在循环中使用这个函数,直至遇到文件尾

    • 从追迹文件中读取行时,fscanf 将很有用
      —— L 10,1
      —— M 20,1

    示例

    FILE * pFile; //pointer to FILE object
    
    pFile = fopen ("tracefile.txt","r"); //open file for reading
    
    char identifier;
    unsigned address;
    int size;
    // Reading lines like " M 20,1" or "L 19,3"
    
    while(fscanf(pFile,“ %c %x,%d”, &identifier, &address, &size)>0){
        // Do stuff
    }
    
    fclose(pFile); //remember to close file when done
    

    malloc / free

    • 使用 malloc 来在堆上分配内存
    • 一定要 free 掉你 malloc 的东西,不然可能导致内存泄漏
      —— some_pointer_you_malloced = malloc(sizeof(int));
      —— free(some_pointer_you_malloced);
    • 不要去 free 你没分配过的内存

    Part(b)

    高效矩阵转置

    • 矩阵转置(A => B)


      转置
    • 如何利用缓存来优化这个操作?

    相关文章

      网友评论

          本文标题:Cache Lab Implementation and Blo

          本文链接:https://www.haomeiwen.com/subject/vwcvnqtx.html