저는 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에 이런 질문을 했는데, 잘못된 곳인 것 같아요.