A method for measuring system calls of linux file system

Use a few C codes to check the file system related system call time and the performance difference with the standard I/O library functions. Mainly take the read and fread functions as an example.

1.1.1  read system call overhead

Let's simulate the overhead of the read system call,

code show as below:

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

 

intmain()

{

      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);

}

Create the input file file.in as follows:

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

Execute the test as follows:

# time ./a.out

real    0m1.080s

user    0m0.064s

sys 0m1.012s

It is found that the main time is spent on sys, that is, kernel mode. Of course, we know that it is a system call, because it is what we wrote.

       You can use strace to trace the program, and the system calls write and read will be displayed continuously.

       Through the test time, we actually calculate the time of a write+read. That is 1.012s/1024000=0.98us.

       The modification procedure is as follows:

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

 

intmain()

{

      char c;

      int in,out;

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

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

           ;

      exit(0);

}

       In the program, the write is removed and only the read system call is left. The running time is as follows:

# time ./a.out

real    0m0.222s

user    0m0.012s

sys   0m0.208s

It can be calculated that the approximate time of each read is 0.208/1024000=0.2us. Running on different machines will have different results, you can test it yourself, I wish you a happy playing.

The program will be optimized later.

1.1.2  read system call overhead 2

Optimize the code as follows:

#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);

}

       The number of bytes in one read is modified to 1024 bytes.

After execution as follows,

# time ./a.out

real    0m0.002s

user    0m0.000s

sys 0m0.000s

It is found that the execution time has been greatly reduced, and the performance has been optimized. In theory, it should be a thousand times faster. After all, the number of system calls has been reduced by a thousand times.

1.1.3  Standard I/O Library

The standard I/O library is a general interface provided by stdio and the header file stdio.h for the underlying I/O system calls, such as fopen, fread, fclose, etc. It is now part of ANSI Standard C.

1.1.4  Performance Differences

Use the functions of the standard I/O library to test, the code is as follows,

#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 结构里使用了一个内部缓冲区。只有在缓冲区满时候才进行底层系统调用再刷数据,当然比直接系统调用快很多了。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325536468&siteId=291194637