实验1 Cache模拟器的实现

 .实验目的

(1)加深对Cache的基本概念、基本组织结构以及基本工作原理的理解。

(2)掌握Cache容量、相联度、块大小对Cache性能的影响。

(3)掌握降低Cache不命中率的各种方法以及这些方法对提高Cache性能的好处。

(4)理解LRU与随机法的基本思想以及它们对Cache性能的影响。

二、实验内容和步骤

1、启动CacheSim

 

 

2、根据课本上的相关知识,进一步熟悉Cache的概念和工作机制。

3、依次输入以下参数:Cache容量、块容量、映射方式、替换策略和写策略。

Cache容量

块容量

映射方式

替换策略

写策略

256KB     

8 Byte

直接映射

------

-------

64KB

32 Byte

4路组相联

LRU

-------

64KB

32 Byte

4路组相联

随机

--------

8KB

64 Byte

全相联

LRU

---------

4、读取cache-traces.zip中的trace文件。

5、运行程序,观察cache的访问次数、读/写次数、平均命中率、读/写命中率。

.实验结果分析

1Cache的命中率与其容量大小有何关系?

 











Cache容量

块容量

映射方式

替换策略

写策略

命中率

8KB

32 Byte

直接映射

------

Write through

96.5519%

32KB

32 Byte

直接映射

------

Write through

98.2644%

64KB

32  Byte

直接映射

------

Write through

98.5404%

128KB

32 Byte

直接映射

------

Write through

98.6606%

256KB

32 Byte

直接映射

------

Write through

98.7066%

512KB

32 Byte

直接映射

------

Write through

98.8148%

1024KB

32 Byte

直接映射

------

Write through

98.8188%

2048KB

32  Byte

直接映射

------

Write through

98.8194%

由表可得:Cache容量越大,其CPU的命中率就越高。Cache命中率随着cache的容量增大而增大。容量小时cache命中率提高速度快,cache容量变大时,命中率提高速度逐渐下降。所以容量也没必要太大,太大会增加成本,而且当容量达到一定值时,命中率已不因容量的增大而有明显的提高。因此Cache容量是总成本与命中率的折中值。

 

  2Cache块大小对不命中率有何影响?

 










Cache容量

块容量

映射方式

替换策略

写策略

命中率

256KB

8 Byte

直接映射

------

Write through

95.8346%

256KB

32 Byte

直接映射

------

Write through

98.7066%

256KB

64 Byte

直接映射

------

Write through

99.1904%

256KB

128Byte

直接映射

------

Write through

99.3965%

256KB

256Byte

直接映射

------

Write through

99.5197%

256KB

512Byte

直接映射

------

Write through

99.396%

256KB

1024 Byte

直接映射

------

Write through

99.3601%

256KB

2048 Byte

直接映射

------

Write through

99.241%

经过表中数据分析得出,随着块大小的增大时,cache的命中率增大,当块长增加到一定程度后,再次增大块大小的时候,命中率开始减小。

    分析块长与命中率之间的关系较为复杂,它取决于各程序的局部特性,当块由小到大增长时,起初会因局部性原理使命中率有所提高。由局部性原理指出,在已被访问字的附近,近期也可能被访问,因此,增大块长,可将更多有用字存入缓存,提高其命中率。可是,如果继续增大块长,命中率有可能下降,这是因为所装入缓存的有用数据反而少于被替换掉的有用数据。由于块长的增大,导致缓存中块数的减少,而新装入的块要覆盖就块,很可能出现少数块刚刚装入就被覆盖,因此命中率反而下降。再者,块增大后,追加上的字距离已被访问的字更远,故近期被访问的可能性会更少。

 

3、替换算法和相联度大小对不命中率有何影响?

替换算法:

FIFO算法:


LFU算法:

 

LRU算法:

 

Random法:

 

FIFO算法:

 

LFU算法:



相联度:

相联度为32时:

 

相联度为16时:

 

相联度为8时:

 

相联度为4


相联度为2

 

 相联度为64

 

 

Cache容量

块容量

映射方式

替换策略

命中率

64KB

32 Byte

组相连映射

FIFO

5.73938%

64KB

32Byte

组相连映射

LFU

5.73938%

64KB

32Byte

组相连映射

Random

98.7122%

128KB

32 Byte

全相连映射

FIFO

63.1661%

128KB

32 Byte

全相连映射

LFU

63.1661%

Cache容量

块容量

映射方式

替换策略

命中率

64KB

128 Byte

组相连映射

LRU

98.7777%

64KB

64Byte

组相连映射

LRU

98.7636%

64KB

32Byte

16组相连映射

LRU

98.7733%

64KB

32Byte

8组相连映射

LRU

98.77%

64KB

32 Byte

4组相连映射

LRU

98.7636%

64KB

32 Byte

2组相连映射

LRU

98.745%

 

替换算法中:LRU算法的平均命中率比FIFO的高
LRU算法比较好地利用访存局部性原理,替换出近期用得最少的字块,它需要随时记录cache 各个字块使用情况。FIFO不需要记录各个字块的使用情况,比较容易实现开销小,但是没有根据访存的局部性原理,最早调入的信息可能以后还要用到,或经常用到例如循环程序;
Cache 容量一定时,随着相联度的不断增加,不命中率渐渐减小


.实验心得

通过这次试验让我更熟悉的掌握了第四章高速缓冲存储器的基础内容,然后由书中知道了cache发展历程,基本工作原理;对实验所需要的重点名词,进行了理解;命中率,访问效率,平均访问时间例题进行了理解,从而分析了Cache容量,相关度,块大小,替换算法对命中率的影响;因为LRU 、FIFO 、RANDOM替换算法对命中率也有这一些影响; 看了主存地址映射:有直接映射组相联映射、全相映射组相联映射有点麻烦,不太好理解。 
不是太容易理解了,然后百度搜了一些相连度大小对命中率影响,然后运用CacheSim模拟器,仅仅从一个数值中值看出来简单的变化;然后查阅课本知道了为什么会存在着现象;这种实践让在学习知识点的过程中,印象更加深刻了。

 

 

 


  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,实现一个cache模拟器可以分为以下几个步骤: 1. 定义cache结构体 我们需要定义一个结构体来表示cache的属性,比如cache的大小、块大小、关联度等等。 ```c typedef struct { int cache_size; // cache大小 int block_size; // 块大小 int associativity; // 关联度 int num_blocks; // 块数 int num_sets; // 集数 int offset_bits; // 偏移量位数 int index_bits; // 索引位数 int tag_bits; // 标记位数 int cache_hits; // 命中次数 int cache_misses; // 未命中次数 int **cache; // 二维数组,表示cache } cache_t; ``` 2. 初始化cache 在初始化cache时,需要根据cache的属性计算出相应的位数、块数和集数,并且要为cache分配相应的内存空间。 ```c cache_t *init_cache(int cache_size, int block_size, int associativity) { cache_t *cache = (cache_t *)malloc(sizeof(cache_t)); cache->cache_size = cache_size; cache->block_size = block_size; cache->associativity = associativity; cache->num_blocks = cache_size / block_size; cache->num_sets = cache->num_blocks / associativity; cache->offset_bits = log2(block_size); cache->index_bits = log2(cache->num_sets); cache->tag_bits = 32 - cache->offset_bits - cache->index_bits; cache->cache_hits = 0; cache->cache_misses = 0; cache->cache = (int **)malloc(sizeof(int *) * cache->num_sets); for (int i = 0; i < cache->num_sets; i++) { cache->cache[i] = (int *)malloc(sizeof(int) * associativity); for (int j = 0; j < associativity; j++) { cache->cache[i][j] = -1; } } return cache; } ``` 3. 实现cache的读写操作 在cache的读写操作中,需要首先计算出相应的标记位和索引位,然后根据关联度和替换策略找到相应的块。 ```c void cache_read(cache_t *cache, unsigned int address) { unsigned int tag = address >> (cache->offset_bits + cache->index_bits); unsigned int index = (address >> cache->offset_bits) & ((1 << cache->index_bits) - 1); for (int i = 0; i < cache->associativity; i++) { if (cache->cache[index][i] == tag) { cache->cache_hits++; return; } } cache->cache_misses++; // 没有命中,进行替换 int replace_index = rand() % cache->associativity; cache->cache[index][replace_index] = tag; } void cache_write(cache_t *cache, unsigned int address) { cache_read(cache, address); } ``` 4. 测试cache模拟器 我们可以编写一个测试函数,读取一个数据集中的地址序列,并且统计cache的命中次数和未命中次数。 ```c void test_cache(cache_t *cache, char *filename) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { printf("Failed to open file!\n"); return; } unsigned int address; char operation[10]; while (fscanf(fp, "%s %x", operation, &address) != EOF) { if (strcmp(operation, "R") == 0) { cache_read(cache, address); } else if (strcmp(operation, "W") == 0) { cache_write(cache, address); } } fclose(fp); printf("Hits: %d\n", cache->cache_hits); printf("Misses: %d\n", cache->cache_misses); printf("Hit rate: %.2f%%\n", (float)cache->cache_hits / (cache->cache_hits + cache->cache_misses) * 100); } ``` 完整代码如下:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值