#cache #simulator #config-file

cachesim

一个可扩展的缓存模拟器

4 个版本

0.1.3 2022年5月25日
0.1.2 2022年5月24日
0.1.1 2022年5月24日
0.1.0 2022年5月24日

#123 in 模拟

每月 21 次下载

MIT 许可证

21KB
238

cachesim

一个高度可扩展的缓存模拟器

cachesim 为缓存模拟器提供了一个高度可扩展的框架。可以使用这个工具不仅来模拟传统的缓存行为,还可以引入自己的缓存类型,甚至在其他存储层次中引入其他级别的存储,这将为存储和内存研究带来益处。

我已经创建了一个示例,将这个crate作为库在一个本地Rust项目中使用。请参阅 cachesim_example


基本用法如下

use cachesim::{CacheDevice, DefaultCache, general_cache_behavior::*};

fn main() {
    // To simulate a cache, firstly build a Cache Device, 
    // given a Cache struct and a config file to initialize the cache.
    let mut cache = CacheDevice::new(DefaultCache::new(), "path\\to\\config\\file");

    // The total size of the cache in bytes could be get by get_size().
    println!("cache size:{}B", cache.get_size());

    for i in 0..16 {
        // Access the cache by giving a u32 represented address to access().
        // The result will be returned in a tuble of (AccessResult, f64).
        let AccessResult(r, l) = cache.access(i);

        // If you want to check the result for a single access, use match.
        println!("{}", match r {
            HitOrMiss::Hit => "hit",
            HitOrMiss::Miss => "miss",
        });
    }

    // The total results of all the operations from construction are recorded.
    // To get these results, use get_result(). A tuple (u32, u32, f64) will be 
    // returned, representing hit count, miss count and total access latency.
    let (h, m, l) = cache.get_result();
    println!("total results: hits={}, misses={}, latency={}", h, m, l);

    // The recorded results could be cleared by clear_result().
    cache.clear_result();
}

要引入一种新的缓存类型,你不需要修改源代码。例如,如果你想引入一个'Oracle Cache',首先你可以在你的项目目录下创建一个名为'oracle_cache.rs'的文件或一个名为'oracle_cache/mod.rs'的模块。然后,定义一个代表缓存的 struct

pub struct OracleCache {
    cachetype:String
    // other field may be needed.
}

然后,为你的新缓存类型实现 GeneralCacheBehavior

use crate::cache_behav::{general_cache_behavior::*};

impl GeneralCacheBehavior for OracleCache {
    // Methods below need to be implemented.
    fn init(&mut self, filename:&str) -> Result<(), String> { ... }
    fn get_type(&self) -> &str { ... }
    fn access(&mut self, _addr:u32) -> AccessResult { ... }
    fn clear(&mut self) { ... }
    fn size(&self) -> usize { ... }
}

你可以为缓存实现任何其他方法。

然后,在你的项目中使用你自己的缓存

use cachesim::{CacheDevice, general_cache_behavior::*};
// Import your own cache.
mod oracle_cache;
use oracle_cache::OracleCache;

fn main() {
    // Use your own cache by passing it to CacheDevice.
    let mut cache = CacheDevice::new(OracleCache::new(), "path\\to\\config\\file");
}

通过这种方式,你甚至可以通过定义和实现几个组织良好的 struct 来引入层次化存储架构。


要使用示例缓存,你需要提供一个配置文件。

对于默认缓存,你的文件需要包含以下内容,格式严格,每行出现一次

  • type=default$ # 这不得更改
  • sets=<u32>$ # 定义缓存中集的数量
  • associativity=<u32>$ # 定义一个缓存集中方式的数量(关联性)
  • blocksize=<u32>$ # 定义缓存行(块)的尺寸(以字节为单位)
  • 命中延迟=<f64>$
  • miss penalty=<f64>$ # 这两个配置定义了缓存的延迟特性,这些浮点数的单位不需要且不能在此处写入

这些行中不要添加任何空白,并在每行末尾添加'$'。

对于Oracle缓存,您的文件需要在单行中包含以下内容

  • type=default$ # 这不得更改

这些行中不要添加任何空白,并在每行末尾添加'$'。

参见 examples/default.txt

无运行时依赖