课程主页:https://courses.cs.washington.edu/courses/cse351/16sp/

课程资料:

实验部分:https://github.com/vuquangtrong/HW-SW_Interface_Course

实验说明:https://courses.cs.washington.edu/courses/cse351/13sp/lab-0.html

课件:http://academictorrents.com/details/b63a566df824b39740eb9754e4fe4c0140306f4b

课程视频:https://www.bilibili.com/video/BV1Zt411s7Gg?from=search&seid=8781593976070799647

参考资料:

https://blog.csdn.net/fang92/article/details/46446467

https://www.cnblogs.com/whuyt/p/4843795.html

https://blog.csdn.net/qq_35578098/article/details/105368368

这次完成Lab4,这次的内容是Cache Geometries,主要是模拟缓存的运行模式。

编译错误

这部分直接编译会产生如下报错:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=cache_64c_2a_16b.o
gcc -Wall cache-test-skel.c cache_64c_2a_16b.o -o cache-test
/usr/bin/ld: cache_64c_2a_16b.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
make: *** [Makefile:10:cache-test] 错误 1

参考了如下资料:

https://blog.csdn.net/qq_35578098/article/details/105368368

得到解决方式如下,将Makefile文件中如下语句

gcc -Wall $(SRC) $(TEST_CACHE) -o $@

修改为

gcc -Wall $(SRC) $(TEST_CACHE) -static -o $@

即可。

再次编译可得:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=cache_64c_2a_16b.o
gcc -Wall cache-test-skel.c cache_64c_2a_16b.o -static -o cache-test

编译成功。

实验内容简介

个人感觉实验内容不太清楚,这里简单说明下。

首先回顾缓存的格式:

我们需要完成如下三个函数:

get_block_size
get_cache_size
get_cache_assoc

第一个函数是求出上图中的$B$,第二个函数是求出上图中的$E$,第三个函数是求出上图中的$S$。

求解思路是类似的:首先在某个地址(不妨设为$0$)获取缓存(access_cache),然后给地址增加固定值,再次获取缓存,每次获取之后判断$0$位置的缓存是否还能获取,如果不能获取则返回对应大小,具体细节后续分别介绍。

Cache Geometries

get_block_size
int get_block_size(void) {
  /* YOUR CODE GOES HERE */
  addr_t address = 0;
  addr_t addr = address;
  int cnt = 0;
  access_cache(addr);
  while (access_cache(addr)){
    addr++;
    cnt++;
    if (!access_cache(address)){
      break;
    }
  }

  return cnt;
}

这里每次对地址增加$1$即可,当access_cache(address)为false时说明起始位置被覆盖,此时返回结果。

get_cache_size
int get_cache_size(int size) {
  /* YOUR CODE GOES HERE */
  int block_size = get_block_size();
  int cnt = 0;
  addr_t address = 0;
  while (1){
    cnt++;
    //清理缓存
    flush_cache();
    for (int i = 0; i < cnt; i++){
      access_cache(i * block_size);
    }
    
    //判断是否覆盖
    if (!access_cache(address)){
      return (cnt - 1) * block_size;
    }
  } 
}

这里地址每次增加$B$,然后在每次大循环之前要清空缓存。

get_cache_assoc
int get_cache_assoc(int size) {
  /* YOUR CODE GOES HERE */
  int cnt = 0;
  addr_t address = 0;
  while (1){
    cnt++;
    //清理缓存
    flush_cache();
    for (int i = 0; i < cnt; i++){
      access_cache(i * size);
    }

    //判断是否覆盖
    if (!access_cache(address)){
      return cnt - 1;
    }
  } 
}

这里地址每次增加$E$,然后在每次大循环之前要清空缓存。

运行结果

cache_64c_2a_16b.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=cache_64c_2a_16b.o
gcc -Wall cache-test-skel.c cache_64c_2a_16b.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 16 bytes
Cache size: 65536 bytes
Cache associativity: 2

cache_32c_8a_8b.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=cache_32c_8a_8b.o
gcc -Wall cache-test-skel.c cache_32c_8a_8b.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 8 bytes
Cache size: 32768 bytes
Cache associativity: 8

cache_16c_4a_4b.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=cache_16c_4a_4b.o
gcc -Wall cache-test-skel.c cache_16c_4a_4b.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 4 bytes
Cache size: 16384 bytes
Cache associativity: 4

mystery0.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=mystery0.o
gcc -Wall cache-test-skel.c mystery0.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 64 bytes
Cache size: 4096 bytes
Cache associativity: 32

mystery1.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=mystery1.o
gcc -Wall cache-test-skel.c mystery1.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 8 bytes
Cache size: 8192 bytes
Cache associativity: 8

mystery2.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=mystery2.o
gcc -Wall cache-test-skel.c mystery2.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 32 bytes
Cache size: 32768 bytes
Cache associativity: 2

mystery3.o:

qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ make cache-test TEST_CACHE=mystery3.o
gcc -Wall cache-test-skel.c mystery3.o -static -o cache-test
qz@qz-virtual-machine:~/桌面/Labs/course-materials4/lab4$ ./cache-test
Cache block size: 16 bytes
Cache size: 4096 bytes
Cache associativity: 1