您的位置:首页 > 移动开发

关于CSAPP 6.18的习题分析

2015-04-22 01:02 295 查看
关于CSAPP 6.18的习题分析

下面的站点能找到我搜集的所有和CSAPP有关的学习资料.

https://github.com/jasonleaster/CSAPP





问题背景:

                 强调一下,问题的针对性很强.在这个题目里面,cache究竟遵循什么策略就是这个题目定的.

其他的策略如果题目没说明,不考虑!题目旨在很简明而要的告诉读者替换策略的一种实现而已.

                  说明了int 的大小是4 byte.这里假设了src 从地址0开始储存, src和dst大小都是是16  bytes,那么 dst的起始地址就是 0x10. 这里只有一级缓存, CPU下面就是一层cache,再往下就是 main memory了.

                    There is a single L1 data cache that is direct-mapped, write-through, and write-allocate, with a block size of 8 bytes.

     题目假设规定了,cache的每个操作都是以 8 byte进行了.

     一开始的时候, cache里面啥也没有.每当我们试图去访问某个变量的时候,我们会先访问cache,看看里面有没有个备份,因为访问cache的速度和访问内存的速度两种不是一个数量级的.

法则:

     如果cache里面有,那么hit.我们就可以直接读取使用这个数据在cache里面的备份.

     如果cache里面没有,从main memory去读取数据,写入到cache中.再从cache中立马读取这个数据.

  对于A问:

                 

 
                   这里重要的就是自己要画个图出来方便理解.答案里面有了.

     对应的你能看到src从0x00开始,dst从0x10开始.

     src的前8byte数据和 dst前8 byte数据都会落在 line 0中.

     src的后8byte和dst的后八个字节会落在 line 1中.

     dst[ j ][ i ] = src[ i ] [ j ].

        

     运行程序前假设cache里什么都没有空数据

        cache里面 line 0 装的是 NULL  NULL

                                            line 1 装的是  NULL  NULL

                  i = 0; j = 0;

                  读取 src[0][0], 第一次访问cache空的 src[0][0] miss.把 src[0][0] src[0][1]都拷贝到cache里去

                           cache里面 line 0 装的是
src[0][0] src[0][1]
                                            line 1 装的是  NULL  NULL

     赋值操作要求写入到dst[0][0] ,访问cache,此时cache里面有dst嘛?没有.line 0 装的 src,line 1空着.

     dst的前8 bytes和 src的前 8 bytes冲突,于是这个时候,把在cache里面的src[0][0] src[0][1]写回内存.

     然后再把dst拷贝到cache line 0.

                           cache里面 line 0 装的是 dst[0][0] dst[0][1]
                                            line 1 装的是  NULL  NULL

                 结论: src[0][0] miss dst[0][0] miss

     如果以上没看懂就反复看,因为上面看不懂下面绝壁白搭...

     i = 0; j = 1;

                 读取src[0][1],  .和之前第一次赋值操作结束后的cache一样.

     由于这时候cache里面的情况是 line 0 装的dst前8 bytes  line 1 空着.

     读取src[0][1]又和cache里现有数据dst冲突,于是又把dst写回到内存,把内存里卖弄的src[0][0] src[0][1]读取到cache line 0.  src[0][1] miss

                           cache里面 line 0 装的是 src[0][0] src[0][1]
                                             line 1 装的是  NULL  NULL

                  开始赋值操作.需要写入的是 dst[1] [0] , 这里需要访问 line 1,line 1此时是空的.于是 dst[1][0] miss.把dst后8 bytes读取到cache的 line 1

     结论: src[0][1] miss dst[1][0]

                  赋值操作完成后

                  此时 cache里面 line 0 装的是 src[0][0] src[0][1] 

                                            line 1 装的是 dst[1][0]  dst[1][1]

                   i = 1; j = 0;

                  读取src[1][0], miss 而且和line 1的dst冲突,需要把dst写回到内存.然后读取src[1][0] src[1][1]到cache

     

      此时 cache里面 line 0 装的是 src[0][0] src[0][1] 

                                            line 1 装的是 src[1][0] src[1][1]

 
                  开始赋值操作.需要写入的是 dst[ 0 ] [ 1 ] , 这里需要访问 line 0,line 0此时是非空的.冲突,里面装着src. 于是把line 0的数据写回内存.把dst[0][0] dst[0][1]读取到cache.

      此时 cache里面 line 0 装的是   dst[0][0] dst[0][1]
                                             line 1 装的是 src[1][0] src[1][1]
                  赋值操作.

     结论: src[0][1] miss dst[1][0] miss

                   i = 1; j = 1;

                  读取src[1][1], hit  cache里面有上次赋值操作后被缓存的src[1][1], 

     

      此时 cache里面 line 0 装的是 src[0][0] src[0][1] 

                                            line 1 装的是 src[1][0] src[1][1]

 

                  开始赋值操作.需要写入的是 dst[ 1 ] [ 1 ] , 这里需要访问 line 1,line 1此时是非空的.冲突 miss,里面装着src. 于是把line 1的数据写回内存.把dst[1][0] dst[1][1]读取到cache.

      此时 cache里面 line 0 装的是 src[0][0] src[0][1] 
                                            line 1 装的是 dst[1][0] dst[1][1]

                   赋值操作.
                  结论 结论: src[1][1] hit dst[1][1]  miss

                   对于B嘛:



 注意  , 这里只改变了cache的大小,cache每次读取写入的数据大小还是没变.8 byte

              

                         @LeDy 看下面这个图,分析方法还是和前面一样,掌握方法,就能自己分析了.



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: