操作系统 | Project_I/O subsystem

一、目的

  1、熟悉类UNIX系统的I/O设备管理
  2、熟悉MINIX块设备驱动
  3、熟悉MINIX RAM盘

二、内容与设计思想

   · 在Minix3中安装一块x MB大小的RAM盘,可以挂载并且存取文件操作。
   · 编写测试文件,测试不同块大小下、不同块扫描方式(顺序/随机)RAM盘和Disk盘的文件读写速度并分析其读写速度差异原因。

三、使用环境

  物理机:Windows10
  虚拟机:Minix3
  虚拟机软件:Vmware
  终端控制软件:MobaXterm
  物理机与虚拟机文件传输:FileZilla

四、实验过程

(1)在Minix3中安装一块RAM盘

   · 修改/usr/src/minix/drivers/storage/memory/memory.c,增加默认的用户RAM盘数。重新编译内核,重启虚拟机。

/* ramdisks (/dev/ram*) */
#define RAMDISKS     7

   · 创建设备mknod /dev/myram b 1 13,并输入ls /dev/ | grep ram查看设备是否创建成功。
在这里插入图片描述
   · 参考/usr/src/minix/commands/ramdisk/ramdisk.c,实现buildmyram.c容量初始化工具,将单位从KB修改为MB。同时,在同一目录下的Makefile文件中添加相应条目。重新编译内核,重启虚拟机。

#define KFACTOR 1048576
PROG=   ramdisk
PROG=   buildmyram

   · 执行命令 buildmyram /dev/myram,创建一个RAM盘。
在这里插入图片描述
   · 在RAM盘上创建内存文件系统,mkfs.mfs /dev/myram。
   · 将RAM盘挂载到用户目录下,mount /dev/myram /root/myram,输入df查看是否挂载成功。
在这里插入图片描述
  注意:重启后用户自定义的RAM盘内容会丢失,因此每次重启后都需要重新设置大小,创建文件系统并挂载。

(2)编写测试代码

   · 主函数实现思路:
  分别调用相应函数测试在顺序和随机两种块扫描方式下,RAM盘和Disk盘多个进程并发读写不同大小块的时间,并计算平均读写速度。
   - 为每个进程分配独立的文件
   - wait(NULL)函数等待所有子进程读写结束再记录结束时间
   - 经测试,进程并发度在7~10之间吞吐量达到最大,基于此在实验中可以修改并发度大小来获得良好的实验数据

for(int blocksize=64;blocksize<=1024*32;blocksize=blocksize*2){
            int Concurrency=7;
            gettimeofday(&starttime, NULL);
            for(int i=0;i<Concurrency;i++){
                if(fork()==0){
                //随机写
                //write_file(blocksize,true,filepathDisk[i]);
                //write_file(blocksize,true,filepathRam[i]);
                
                //顺序写
                //write_file(blocksize,false,filepathDisk[i]);
                //rite_file(blocksize,false,filepathRam[i]);
                
                //随机读
                read_file(blocksize,true,filepathDisk[i]);
                //read_file(blocksize,true,filepathRam[i]);
                
                //顺序读
                //read_file(blocksize,false,filepathDisk[i]);
                //read_file(blocksize,false,filepathRam[i]);
                exit(0);
                }
            }
            //等待所有子进程结束
            //wait失败返回-1
            while(wait(NULL)!=-1);
            gettimeofday(&endtime, NULL);
            spendtime=get_time_left(starttime,endtime)/1000.0;//换算成秒
            int block=blocksize*Concurrency*times;
            printf("blocksize_KB=%.4fKB,speed=%fMB/s\n",(double)blocksize/1024.0,(double)block/spendtime/1024.0/1024.0);
    }

   · write_file & read_file函数实现思路:
  通过多次重复的读写操作来计算RAM盘/Disk的读写速度。
   - 若为随机读写,则每次读写结束后利用lseek(fp,rand()%(filesize-blocksize),SEEK_SET)函数定位到文件任意位置。
   - 为了减小主机操作系统的缓存机制造成的误差,将文件大小filesize设置为300MB
  注意:对(filesize-blocksize)取余,防止写出文件

//blocksize表示写的块大小
//isrand=true表示随机写,否则为顺序写
//filepath为文件写的路径
void write_file(int blocksize, bool isrand, char *filepath){
    int fp=open(filepath,O_RDWR|O_CREAT|O_SYNC,0755);
    if(fp==-1) printf("open file error!\n");
    int res;
    //多次重复写入计算时间
    for(int i=0;i<times;i++){
        if((res=write(fp,buff,blocksize))!=blocksize){
            printf("%d\n",res);
            printf("write file error!\n");
        }
        if(isrand){
            //随机生成一个整数 取余定位到文件中任意位置
            //对(filesize-blocksize)取余,防止写出文件
            lseek(fp,rand()%(filesize-blocksize),SEEK_SET);
        }
    }
    lseek(fp,0,SEEK_SET);
}

void read_file(int blocksize,bool isrand,char *filepath){
    int fp=open(filepath,O_RDWR|O_CREAT|O_SYNC,0755);
    if(fp==-1) printf("open file error!\n");
    int res;
    for(int i=0;i<times;i++){
        if((res=read(fp,readbuff,blocksize))!=blocksize){
            printf("%d\n",res);
            printf("read file error!\n");
        }
        if(isrand){
            lseek(fp,rand()%(filesize-blocksize),SEEK_SET);
        }
    }
    lseek(fp,0,SEEK_SET);
}

   · get_time_left函数实现思路:
  利用测试得到的starttime和endtime计算读写所耗费的时间。

long get_time_left(struct timeval starttime,struct timeval endtime){
    long spendtime;
         //换算成毫秒
    spendtime=(long)(endtime.tv_sec-starttime.tv_sec)*1000+(endtime.tv_usec-starttime.tv_usec)/1000;
    return spendtime;
}

五、实验结果

(1)实验数据表

随机写64B128B256B512B1KB2KB4KB8KB16KB32KB
磁盘0.2443.2555.0866.1048.13810.65212.07914.42215.45226.042
RAM盘2.6316.1049.76621.04742.09373.42697.656167.650233.907260.417
顺序写64B128B256B512B1KB2KB4KB8KB16KB32KB
磁盘2.5895.02610.35820.71532.94441.430131.777164.474170.898201.613
RAM盘3.5907.39812.20729.59339.06378.125156.25188.253234.962454.546
随机读64B128B256B512B1KB2KB4KB8KB16KB32KB
磁盘1.70893.4186.835910.357516.472123.572132.944343.7545.289856.9661
RAM盘1.83844.0697.353632.55258.829183.4669180.8449267.5514312.5374.7002
顺序读64B128B256B512B1KB2KB4KB8KB16KB32KB
磁盘2.0596.835919.531339.062559.1856156.25165.7197260.4167312.5437.5
RAM盘5.026510.357520.71542.744682.8598165.7197218.75331.4394437.5527.1084

  注:读写速率的单位:MB/s

(2)实验数据图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)实验结果分析

  总体来看,写的速率比读的速率慢,随机读写的速率比顺序读写的速率慢,尤其是磁盘两种快扫描方式的速率差异更加明显。究其原因在于磁盘读写时,机械寻道是影响磁盘读写速率的主要因素,随机读写每次都需要重新寻道,而顺序读写只需要在第一次进行寻道,因此两种方式的读写速率差别很大。
  对比Disk盘和RAM盘,RAM盘的读写速率普遍快于Disk盘,特别是随机读写性能。由于RAM盘为内存分配的一块区域,因此没有寻道和旋转延迟,所以RAM的读写速率优于Disk。但对Disk进行一次读后,其内容会被缓存,之后再次读Disk上的数据,其效率有所提高。

完整代码与测试文件: https://github.com/RachelllYe/OSProject
欢迎探讨与指正,谢谢!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值