私はUnix
オペレーティングシステムベースのシステムの内部動作を理解しようとしています。バッファリングされた I/O を読み取り、バッファー・サイズがシステム呼び出しの数とプログラムのコピーにかかる合計時間にどのような影響を与えるかを読み取ります。まず、これは私のプログラムです。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
long currentTimeMillis();
int main(int argc, char *argv[]) {
int bufsize = atoi(argv[3]);
printf("copying with buffer size %d\n", bufsize);
char buf[bufsize];
//open the file
int fd_from = open(argv[1], O_RDWR);
if(-1 == fd_from) {
printf("Error opening source file\n");
return -1;
}
//file to be copied to
int fd_to = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(-1 == fd_to) {
printf("Error opening destination file\n");
return -1;
}
//copy
long startTime = currentTimeMillis();
int bytes_read = 0;
long totalTimeForRead = 0;
long totalTimeForWrite = 0;
while(1) {
long readStartTime = currentTimeMillis();
int bytes_read = read(fd_from,buf,bufsize);
long readEndTime = currentTimeMillis();
if(0 == bytes_read) {
break;
}
if(-1 == bytes_read) {
printf("Error occurred while reading source file\n");
return -1;
}
totalTimeForRead += readEndTime - readStartTime;
long writeStartTime = currentTimeMillis();
int bytes_written = write(fd_to,buf,bufsize);
long writeEndTime = currentTimeMillis();
totalTimeForWrite += (writeEndTime - writeStartTime);
if(-1 == bytes_written) {
printf("Some error occurred while writing file\n");
return -1;
}
}
long endTime = currentTimeMillis();
printf("Total time to copy%ld\n", endTime - startTime);
printf("Total time to write%ld\n", totalTimeForWrite);
printf("Total time to read%ld\n", totalTimeForRead);
}
long currentTimeMillis() {
struct timeval time;
gettimeofday(&time, NULL);
return time.tv_sec * 1000 + time.tv_usec / 1000;
}
私は2.9GHz Intel i7を搭載した16G MacBook Proを使用しています(この情報が役に立つ場合)。ソースファイルサイズは2.8Gです。合計時間がread()
はるかに短くて少し驚きましたwrite()
。バッファサイズが16Kの場合、次のように見つかりました。
./a.out largefile dest 16382
copying with buffer size 16382
Total time to copy5987
Total time to write5330
Total time to read638
私が読んだところでは、write()
データはユーザーバッファからカーネルバッファに転送された直後に返されます。したがって、かかる時間は、この時間+システムコールが開始されるのにかかる時間です。read()
また、カーネルバッファからユーザバッファに読み込まれるため、必要な合計時間は同じでなければなりません(どちらの場合もディスクI / Oはありません)。
それでは、なぜ結果に大きな違いがありますか? SOにこんな質問をしましたが、間違ったところだと思います。