作者 陈浩
安装完成后,在 ssdmodel/valid 目录下有个 runvalid 文件,这是一个自带的测试脚本。打开这个文件可以看到如何来使用这个模拟器。下面是截取的几条命令:
echo “Sequential read (250K I/Os): average SSD response time should be around 0.132 ms”
$PREFIX/disksim ssd-sr250k.parv ssd-sr250k.outv ascii 0 1
grep “ssd Response time average:” ssd-sr250k.outv | grep -v “#”
可执行程序是位于 src 目录下的 disksim。Disksim 的运行格式为:disksim <parfile> <outfile> <tracetype> <tracefile> <synthgen> [par_override…]
其中的各个参数的含义分别如下:
parfile
参数文件,可以在这个文件里面配置模拟器的各个参数。
下面给出参数文件设置的一个示例:
ssdmodel_ssd SSD {
Reserve pages percentage = 15, # 预留空间百分比
Minimum free blocks percentage = 5, # 最少空白块比例,否则触发gc
Write policy = 2, # 写策略
Cleaning policy = 2, # gc策略
Planes per package = 8,
Blocks per plane = 2048,
Plane block mapping = 3,
Copy back = 1, # 是否开启 copy back
Number of parallel units = 1, # 并行单元的大小
Allocation pool logic = 1,
Elements per gang = 1,
Gang share = 1, #
Cleaning in background = 0, # 是否开启后台GC
Command overhead = 0.00, # 指令执行时间
Bus transaction latency = 0.0, # 总线处理延迟
Bulk sector transfer time = 0,
Flash chip elements = 8,
Page size = 8, # page大小,8*512 B
Pages per block = 64,
Blocks per element = 16384,
Element stride pages = 1,
Never disconnect = 1,
Print stats = 1,
Max queue length = 20,
Timing model = 1,
Chip xfer latency = 0.000025, #每个字节的传输延迟
Page read latency = 0.025, #读延迟
Page write latency = 0.200, #写延迟
Block erase latency = 1.5
#擦除延迟
} # end of SSD spec
outfile
输出文件,模拟器的仿真结果会在输出文件里面,可以在参数文件里面设置在输出文件里面输出哪些内容。
tracetype
确定输入trace的格式。比如:ASCII HPL HPL2 DEC VALIDATE RAW ATABUS IPEAK P OSTGRES EMCSYMM DEFAULT(ASCII)等等。
Disksim本身支持的trace类型是有限的,如果不支持实验使用的trace,则需要修改disksim源程序以添加新的trace类型,具体可参考官方手册。
tracefile
输入的trace文件。 如果为 0 的话表示使用系统自动生成的trace数据。如果这个参数为 0 ,那么 synthgen 参数必须要大于0,表示开启合成负载。
synthgen
决定合成负载部分的模拟器是否打开(除0外的数表示开启)。
par_override
这是一个可选参数,在这里可以重写参数,允许默认参数值或者parfile文件中的参数值替换为命令行指定的值。
除了 disksim 这个可执行程序外,在src目录下,还有一个 syssim 可执行程序。也可以通过这个可执行程序来模拟。syssim 对应的 main 函数在是src/syssim_driver.c 中。其中的核心代码如下:
for (i=0; i < 1000; i++) {
r.start = now;
r.flags = DISKSIM_READ;
r.devno = 0;
r.blkno = BLOCK2SECTOR*(DISKSIM_lrand48()%(nsectors/BLOCK2SECTOR)); // 随机生成 blkno
r.bytecount = BLOCK;
completed = 0;
disksim_interface_request_arrive(disksim, now, &r); //发送请求
while(next_event >= 0) { // 当前请求全部完成了才会发送下一个请求
now = next_event;
next_event = –1;
disksim_interface_internal_event(disksim, now, 0);//处理未完成的事件
}
if (!completed) {
fprintf(stderr,“%s: internal error. Last event not completed %d\n”, argv[0], i);
exit(1);
}
}
上面的代码实现的是向模拟器发送1000个请求,其中一个关键的函数是disksim_interface_request_arrive(),在这里它直接将模拟器当成一个黑盒子,然后通过调用这个函数,来给模拟器发送请求。上面的1000个请求都是等上一请求全部完成时才会发送下一个请求。很显然这是不符合实际情况的,毕竟在这里只是给了一个示例。值得注意的两点是,请求的 blkno 和 bytecount。不管使用 ssdsim 还是 hddsim, disksim 内部操作的块都是以512B为单位,所以请求的 blkno 的单位为 512B,对于 hdd 而言,大小可以任意,而对ssd而言其必须为4k的整数倍,即该值必须是8的整数倍。 bytecount 的单位是字节,对于 ssd 而言同样应该是 4k 的倍数,即该值应该为4096的整数倍。