《操作系统课程设计实验报告IO系统调用开销比较.doc》由会员分享,可在线阅读,更多相关《操作系统课程设计实验报告IO系统调用开销比较.doc(12页珍藏版)》请在三一办公上搜索。
1、 I/O系统调用开销比较任务目的:了解I/O系统调用的特点,并通过性能测试增强直观认识。任务要求:Linux平台用C变成实现文本文件内容的倒序。分别使用三种方法,考虑效率,比较性能。标准C的IO库函数:fopen fread fwriteUnix的函数:open read writeOpen和mmap设计方案:实验的主思路即提供中间容器,将文件中的数据读出存入中间容器,再将容器的内容逐次读入文件内部。其要求在于读入文件的时候实现文件内容的倒序,则要求中间容器的内容从最后一个数据读起,或是在中间容器中早早实现数据内容的倒序。类似于数据的压栈操作和出栈操作,从文件中读出数据压入栈底,再从栈底读出数
2、据写入文件头,中间容器则为栈。为实现对数据的倒序,本任务采取定义一个大容量的数组作为中间的容器,从文件里以要求读取的数据块大小读取文件的内容,同时将读出的数据存入数组中,读完数据可知数组的大小,再重写源文件,实现数组的最后一个元素写入文件头,数组下标不断减少,以所要求写入的数据块大小重新写入文件。针对read和fread每次读取大小有要求,主要在于读取或写入时缓冲区的大小,动态定义缓冲区的大小实现每次读取或写入数据的大小控制。为实现测试文件的内容能完整地存入中间容器,即字符串数组,需要动态申请文件大小的数组,存取文件中的内容。Mmanp指memory-mapped(存储映射)其将文件内容映射到
3、进程地址空间,相比传统的方法而言,减少了系统调用和内容拷贝,无需进行文件内容的读取和写入,减少了完成所需要的时间,提高了整体的效率,从而提高了性能。主要在于数据的重新排序。设计内容:使用标准的C语言I/O库函数。存储结构为数组,使用fopen以只读模式打开源文件,用fread and fwrite 实现数据的读入和写入,其核心代码如下:/读出文件数据 while(!feof(fpout)&iFILESPACE) fread(buff,READSPACE*sizeof(char),1,fpout); for(j=0;jREADSPACE;j+,i+) *(DATE+i)=*(buff+j); f
4、or(k=0;k(FILESPACE/READSPACE);k+) for(j=0;jREADSPACE;j+,i-)/从数组读出数据块存入buff *(buff+j)=*(DATE+i); fwrite(buff,READSPACE*sizeof(char),1,fpin); 使用Unix的I/O库函数。利用文件的底层操作,完成文件内容的读取,打开文件时以读取方式打开,方便文件内容的读取和写入。核心代码如下:size=read(fd,buff,READSPACE*sizeof(char);for(j=0;jREADSPACE;j+) *(DATE+i)=*(buff+j); /printf(
5、%c,*(DATE+i); i+; /存入数组 for(k=0;k(FILESPACE/READSPACE);k+) for(j=0;jREADSPACE;j+,i-) *(buff+j)=*(DATE+i); /printf(%c,*(buff+j); /从数组中倒序存入缓冲区 size=write(fdi,buff,READSPACE*sizeof(char);/写回文件mmap和open。此方式实现地址内容的映射,对共享内存的数据进行了更改,同时也将反映在文件内容,此处只需将数据存储在数组中,再写回到内存中,这样就对文件中的内容实现倒序。核心代码如下:sm=mmap(0,FILESPAC
6、E*sizeof(char),PROT_WRITE|PROT_READ,MAP_SHARED,src,0); while(i0) *sm=DATEFILESPACE-i; sm-; i-; 任务结果性能测试:参与测试的文件有三种大小:4KB、256KB、64MB.每次读取的大小分别为1字节,256字节,4KB和16KB。使用time测试各种文件,读取大小不同其结果的变化规律。测试文件为4KB,分别以1字节、256字节、4KB大小读取,以标准C语言I/O读取实际时间用户CPU时间系统CPU时间1字节0m0.002s0m0.001s0m0.001s256字节0m0.002s0m0.001s0m0.
7、001s4KB0m0.002s0m0.000s0m0.001s测试文件为4KB,分别以1字节、256字节、4KB大小读取,以unix的I/O读取实际时间用户CPU时间系统CPU时间1字节0m0.019s0m0.003s0m0.015s256字节0m0.004s0m0.002s0m0.001s4KB0m0.002s0m0.000s0m0.001s测试文件为4KB,256KB和64MB,以open和mmap读取实际时间用户CPU时间系统CPU时间4KB0m0.020s0m0.003s0m0.015s256KB0m0.006s0m0.002s0m0.003s64MB0m1.398s0m0.802s0
8、m0.149s测试文件为256KB,分别以1字节、256字节、4KB、16KB大小读取,以标准C语言I/O读取实际时间用户CPU时间系统CPU时间1字节0m0.034s0m0.033s0m0.001s256字节0m0.006s0m0.005s0m0.001s4KB0m0.007s0m0.002s0m0.005s16KB0m0.005s0m0.004s0m0.001s测试文件为256KB,分别以1字节、256字节、4KB、16KB大小读取,以unix的I/O读取实际时间用户CPU时间系统CPU时间1字节0m1.233s0m0.088s0m1.138s256字节0m0.021s0m0.002s0m
9、0.010s4KB0m0.004s0m0.002s0m0.002s16KB0m0.008s0m0.004s0m0.004s测试文件为64MB,分别以1字节、256字节、4KB、16KB大小读取,以标准C语言I/O读取实际时间用户CPU时间系统CPU时间1字节0m5.792s0m5.579s0m0.298s256字节0m0.882s0m0.613s0m0.266s4KB0m0.820s0m0.494s0m0.353s16KB0m0.800s0m0.578s0m0.275s测试文件为64MB,分别以1字节、256字节、4KB、16KB大小读取,以unix的I/O读取实际时间用户CPU时间系统CPU
10、时间1字节5m21.923s0m17.469s4m44.656s256字节0m1.774s0m0.548s0m1.210s4KB0m0.603s0m0.493s0m0.178s16KB0m0.534s0m0.488s0m0.146s运行结果分析:从性能测试得到的结果,可以得出以下结论:对于同大小的测试文件,同样读取大小的三个不同的方式,标准C语言I/O库函数花费的总时间相对比较小。对于同大小的测试文件,使用标准C语言I/O库函数,针对不同的读取大小,随着读取大小增加而时间总的趋势有减少。对于同大小的测试文件,使用Unix I/O库函数,针对不同的读取大小,随着读取大小增加而时间总的趋势若减少。
11、对于同大小的测试文件,使用mmap函数,针对不同的读取大小,随着测试文件大小增加而时间总的趋势先减少后增加。感想与体会:待添加的隐藏文字内容2 本次课程设计我学到了很多东西,我的专业知识不是很好,所以我实验做的比较吃力。但是每次课程设计我都很好的向老师同学学习,在他们乐于帮助之下我学到了怎样去写,怎样去调试,怎样把书本上的东西付诸实践。当我把代码写好并运行成功时,那份感觉棒极了,尽管我的代码有些是参考同学的,但我还是从中学到很多,学到了怎样用数组,怎样用指针去存储,怎样用函数等等。我很高兴,但我会继续努力。之前看到老师在新浪微博上的参考资料,我就跟着老师的指导一步一步的做,我很感谢我有这样的老
12、师,每天晚上1点才睡,就是为了我们能够学到知识,就像老师自己说的,您确实做到了,是一位尽职的好老师。这就是我本次课程设计的感想和体会。*实验源代码如下:#include #include #include int main()const long int LEN = (4*1024);FILE * fp;int i;char sLEN; fp = fopen(4kb.txt,r+);fread(s,sizeof(s),1,fp);fseek(fp,0L,SEEK_SET);/把文件指针移动到文件到首部for(i = LEN - 1;i = 0;i -)fwrite(&si,sizeof(cha
13、r),1,fp);fclose(fp);return 0;#include #include #include void reverse(FILE *fp,long int offset,long int buffer) int i,sum; char* buff = (char *)malloc(sizeof(char)*buffer);char c;fseek(fp,0,2);sum = ftell(fp); if(offsetsum-buffer)/当最后一次到文档长度小于buffer时 根据实际长度读取写入 if(offset = sum-buffer)return; fseek(fp
14、,offset,0); fread(buff,sum-offset-1,1,fp); fseek(fp,0,0); for(i = 0;i buffer-1-i;i -) c = buffi; buffi = buffbuffer-1-i; buffbuffer-1-i = c; fwrite(buff,buffer,1,fp); free(buff);int main (int argc,char *argv)/命令+文件名+缓冲区大小(B)FILE *fp;int a,b,c,d; long int buffer = atol(argv2);/缓冲区大小 if(fp = fopen(arg
15、v1,r+)=NULL)printf(open file errorn);return 1; reverse(fp,0,buffer); fclose(fp);for(a = 0;a 40000000;a+)for(b = 0;b 40000000;b+)for(c = 0;c 44440000;c+)d = 0; return 0;#include #include #include #include #include /extern long tell (long fd);/const long int buffer = 1024*1024;void reverse(int id,long
16、 offset,long buffer) int i,sum; char *buff = (char *)malloc(sizeof(char)*buffer);char c;sum = lseek(id,0,2); if(offset=sum-buffer)/当最后一次到文档长度小于buffer时 根据实际长度读取写入 free(buff);buff = (char *)malloc(sizeof(char)*(sum-buffer+1); lseek(id,offset,0); read(id,buff,sum-offset+1); lseek(id,0,0);/if(buffsum-of
17、fset+1=n)/sum-; for(i = 0;i buffer-1-i;i -) c = buffi; buffi = buffbuffer-1-i; buffbuffer-1-i = c; write(id,buff,strlen(buff); / printf(%d,strlen(buff);int main (int argc,char *argv)/命令+文件名+缓冲区大小(B) long int buffer = atol(argv2); int id; if(id = open(argv1,O_RDWR)=-1)printf(open file errorn);return 1; printf(open successn);reverse(id,0,buffer); close(id); return 0;