linux文件系统系统调用实测的一个方法

简介:


通过几个C代码来检测一下文件系统相关系统调用时间,以及和标准I/O库函数的性能差异。主要以read和fread函数为例。

1.1.1 read系统调用开销

我们来模拟一下read系统调用的开销情况,

代码如下:

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

 

int main()

{

      char c;

      int in,out;

      in = open("file.in",O_RDONLY);

      out=open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);

      while(read(in,&c,1)==1)

           write(out,&c,1);

      exit(0);

}

创建输入文件file.in如下:

dd if=/dev/zero of=file.in bs=1 count=1024000

执行测试如下:

# time ./a.out

real    0m1.080s

user    0m0.064s

sys   0m1.012s

发现主要时间是花在了sys上的,即内核态,当然我们知道是系统调用了,因为就是我们写的嘛。

       可以使用strace来跟踪程序,就会不断显示系统调用write和read了。

       通过测试时间,其实我们计算得到一次write+read的时间的。就是1.012s/1024000=0.98us。

       修改程序如下:

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

 

int main()

{

      char c;

      int in,out;

      in = open("file.in",O_RDONLY);

      while(read(in,&c,1)==1)

           ;

      exit(0);

}

       程序中,去掉了write只留下了read系统调用,运行后时间如下:

# time ./a.out

real    0m0.222s

user    0m0.012s

sys   0m0.208s

可以计算得到每次read的大概时间为0.208/1024000=0.2us.在不同的机器上运行会有不同的结果,大家可以自行测试,祝玩的愉快。

后续会将该程序进行优化。

1.1.2 read系统调用开销二

将代码进行优化如下:

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

 

int

main ()

{

  char block[1024];

  char c;

  int in, out;

  in = open ("file.in", O_RDONLY);

  out = open ("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);

  while (read (in, block, sizeof(block)) >0 )

    write (out, &c, 1);

  exit (0);

}

       一次read的字节数量修改为1024个字节。

执行后如下,

# time ./a.out

real    0m0.002s

user    0m0.000s

sys 0m0.000s

发现执行时间大幅降低了,性能得到了优化,理论上应该快了千倍被,毕竟系统调用次数减少了千次。

1.1.3 标准I/O库

标准I/O库是由stdio及头文件stdio.h为底层i/o系统调用提供的一个通用接口,例如fopen,fread,fclose等。现在是ANSI标准C的一部分。

1.1.4 性能差异

使用标准I/O库的函数来进行测试,代码如下,

#include <stdio.h>

#include <stdlib.h>

int

main ()

{

      int c;

      FILE  *in,*out;

 

     

  in = fopen ("file.in", "r");

  out = fopen ("file.out", "w");

  while((c=fgetc(in))!=EOF)

        fputc(c,out);

  exit (0);

}

编译执行,

# time ./a.out

real    0m0.036s

user    0m0.032s

sys   0m0.000s

       发现sys时间几乎为0,说明主要是在用户态的操作,相比read系统调用所化时间(如下)快了很多。

real    0m1.080s

user    0m0.064s

sys   0m1.012s

       这个主要是因为在 stdio 库在 FILE 结构里使用了一个内部缓冲区。只有在缓冲区满时候才进行底层系统调用再刷数据,当然比直接系统调用快很多了。
目录
相关文章
|
2天前
|
Linux
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
|
4天前
|
存储 缓存 Linux
【Linux】文件系统
在打开文件之前,我们需要找到文件 -> 就要从磁盘中找到对应文件 -> 通过文件路径与文件名
19 4
|
1天前
|
Linux Windows 存储
|
2天前
|
Linux
Linux如何查询较大文件的方法
【5月更文挑战第8天】Linux如何查询较大文件的方法
5 0
|
2天前
|
Linux 网络安全
xmanager 4 连接SuSE linux server 11方法
xmanager 4 连接SuSE linux server 11方法
|
2天前
|
存储 算法 Linux
【Linux】详解文件系统以及周边知识
【Linux】详解文件系统以及周边知识
|
3天前
|
Linux 编译器 调度
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
本文介绍了如何将POSIX应用程序编译为在Xenomai实时内核上运行的程序。
19 1
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
|
5天前
|
存储 Linux 编译器
【探索Linux】P.13(文件系统 | 软硬链接 | 动态库和静态库)
【探索Linux】P.13(文件系统 | 软硬链接 | 动态库和静态库)
12 0
|
6天前
|
Shell Linux 编译器
C语言,Linux,静态库编写方法,makefile与shell脚本的关系。
总结:C语言在Linux上编写静态库时,通常会使用Makefile来管理编译和链接过程,以及Shell脚本来自动化构建任务。Makefile包含了编译规则和链接信息,而Shell脚本可以调用Makefile以及其他构建工具来构建项目。这种组合可以大大简化编译和构建过程,使代码更易于维护和分发。
23 5
|
6天前
|
存储 Linux Shell
Linux文件系统
Linux文件系统
17 2