针对这几天使用disksim-3.0合成负载的摸索做个总结:
Disksim-3.0是可以支持负载合成的。因为根据manual使用手册:
当synthgen取0的时候是关闭disksim的内置负载合成的。当取为非0的时候(一般取1)开启负载功能,但是输出到XXX.outv的文件中是看不到我们想要的负载文件信息。可以在源码中修改输出,其实可以输出合成负载的,下面将详细描述。先讲一下配置文件中如何设置我们所需的负载合成。
关于XXX.parv配置文件:
在安装成功的disksim的vaild文件下有很多类型的配置文件,关于使用哪些配置文件可以产生合成负载,其实可以查看该目录下的runvaild(这是个shell脚本)。
下面截取其中的关键语句:
可以看到以上的配置文件都是可以支持合成负载的。选取其中syntharrays.parv文件中的配置文件做相关介绍。
这里简要的提一下关于配置文件相关结构:
- 设置整个工程的系统背景参数:disksim_global Global{}里面的东西
- 整个模拟工程局部参数,显示信息收集等:disksim_stats Stats{}里面的东西(iodriver,bus,ctrl,device,process,flow)
- Disksim_iosim IS{}主要是定义系统衡量的时间
- 定义一系列的设备:这里面涉及到设备性能参数的配置,其中会引用.diskspec文件,.diskspec会引用.model文件。这些东西又很复杂了,所以单纯的负载合成最好选择直接能跑得以上配置文件,修改后面的相关配置文件。
- 实例化上述定义的设备:component instantiaton……..
- 实例化的设备的拓扑关系需要链接,因此有system topology…..
- 之后还有一个syncsets这个好像是和磁盘转速同步有关,有些配置文件是不做定义的
- 磁盘阵列,数据逻辑组织形成,disksim_logorg …..(这部分东西涉及到RAID还是striping)
- 负载合成配置开始
负载合成配置有两个地方:
- disksim_pf 的配置,主要是配置和下面有关的disksim_synthio里面用多少个generator(标号从0开始),处理的时间尺度衡量标准,这里没有特别需要修改的。下面是使用手册里面描述的:
- disksim_synthio这才是修改的关键点,里面包含两个部分总体参数配置和每个generator的相关配置(一般多个generator配置是一样的)。先看下使用手册里面描述的关键信息: 上面描述的是disksim_synthio里面的相关配置
- Number of I/O requests to generate:也就是我们想要产生多少的请求数
- Maximum time of trace generated:这些请求产生的时间范围,和之后合成的负载中第一个参数,请求到达时间有关。
- System call/return with each request :没有多大问题就默认吧
- Think time from call to request :没有多大问题就默认
- Think time from request to return :没有多大问题就默认
下面需要提一点,请求到来的时间,还有请求本地特性的都可能服从一定的概率分布,disksim这里就很吊,他能指定合成的概率,看下使用手册定义: 常用的正态分布,指数分布,泊松分布,均匀分布都是有的。配合generator的一个配置讲下:1
2
3
4
5
6Time-limited think times = [ normal, 30.0, 100.0 ],
General inter-arrival times = [ exponential, 0.0, 0.0 ],
Sequential inter-arrival times = [ normal, 0.0, 0.0 ],
Local inter-arrival times = [ exponential, 0.0, 0.0 ],
Local distances = [ normal, 0.0, 40000.0 ],
Sizes = [ exponential, 0.0, 8.0 ]
等式右边并不是某个特定的值,而是用 [ ]括起来的一些量,这些是表示该参数的值不是固定的,对于每次请求该值都不一样。[ ] 里的英文表示分布的类型,具体解释参考上面手册中的解释。
下面关于一个generate的详细配置讲解(参考了一篇博客:)
Generators 生成器的详细配置:
Storage capacity per device :模拟设备的容量,其实就是扇区(页面)的总数目(需要注意这个容量大小是不能随便改的这和上面的磁盘阵列配置,设备参数设置都是有关的,可能和.diskspec和model都是有关的)1
2
3
4Blocking factor 设置的是一个请求的单元大小,如果设为8,则一次请求的(扇区)数目就是8的倍数。
Probability of sequential access = 0.0,
Probability of local access = 0.0,
Probability of read access = 0.66,
以上三个概率的设置就是控制随机请求的比例,局部性还有读写比例
上面的值表示生成的trace全随机,并且读请求占66%;关于local access,manual里面说的是如果一个请求离上一个请求的地址距离在一个较短的距离里面,则这个请求就是local 请求,下面一个 Local distances就设置了这个较短的距离的值。Probability of local access就是local请求的概率(这就是我们负载分析常说的空间局部特性)。
最后要提的是sizes参数,表示每次请求访问的扇区(页面)个数。
上面配置文件的设置大概都讲完了,OK运行命令:
路径/disksim XXX.parv 自己定义的输出文件 ascii 0 1可以开始运行了。但是当你点开输出文件的时候,并有想要的trace记录。这里就需要gdb+源码理解找到输出Trace。
中间的经历反复揣摩和GDB单步调试:
从一开始的disksim_synthio.c文件中的相关函数入手:1
2static void synthio_appendio (process *procp, ioreq_event *tmp)函数尾部输出
//fprintf (stderr, "New request %d, time %f, devno %d, blkno %d, bcount %d, flags %x\n", synthio_iocnt, new->time, new->devno, new->blkno, new->bcount, new->flags);
发现这个输出并不是合成的I/O负载,利用GBD的bt反向推断,我们可以得知负载合成函数在整个系统模拟运行的函数调用关系:1
Disksim_run_simulation函数->Disksim_simulate_event函数->pf_internal_event函数->pf_handle_cpu_event函数->pf_handle_event函数->pf_handle_synthio_event函数->synthio_generate_io_activity函数->同时调用synthio_appendio和synthio_geneartenextio函数。
Disksim_run_simulation其实就是写了while循环反复调用Disksim_simulate_even函数,所以在这个函数上查看入手:
void disksim_simulate_event (int num)函数里面调用了以下函数:
。。。。。。。。1
2
3
4
5
6
7
8
9最后合成的:trace 每条请求如下:
4.911651 0 16350 1 20000003
有5个值,分别是
请求发起的时间 4.911651
访问的设备号 0
访问的块号 16350
该请求读取的块数目 1
标志位 20000003
标志位里保存了trace的相关信息 ,包括读/写 以及是否local request 等
标志信息的定义在disksim_reqflags.h里,如下所示1
2
3
4
5
6
7
8
9
10
11
12
13
14#define DISKSIM_WRITE 0x00000000
#define DISKSIM_READ 0x00000001
#define DISKSIM_TIME_CRITICAL 0x00000002
#define DISKSIM_TIME_LIMITED 0x00000004
#define DISKSIM_TIMED_OUT 0x00000008
#define DISKSIM_HALF_OUT 0x00000010
#define DISKSIM_MAPPED 0x00000020
#define DISKSIM_READ_AFTR_WRITE 0x00000040
#define DISKSIM_SYNC 0x00000080
#define DISKSIM_ASYNC 0x00000100
#define DISKSIM_IO_FLAG_PAGEIO 0x00000200
#define DISKSIM_SEQ 0x40000000
#define DISKSIM_LOCAL 0x20000000
#define DISKSIM_BATCH_COMPLETE 0x80000000
所以上面那条请求的标志位表示了该请求是读请求,time_critical ,Local的请求
通过编写一个小的统计程序来收集生成的trace的信息,证明了生成的trace是满足我们要求的。
但是我们用disksim+flashsim的负载用的是ascii格式,这个标志位在之后需要进行修改:0表示写请求,1表示为读请求。