파일 I/0 버퍼에 대한 인식

1. 파일 I/O의 커널 버퍼
아마도 많은 초보 파일 입출력을 배울 때read()나 write() 시스템 호출이 디스크에 있는 파일에 직접 접근할 것이라고 생각할 것이다. 그렇지 않으면 이 두 호출은 사용자 공간 버퍼와 내부 핵의 고속 버퍼 사이에 데이터를 복제할 뿐이다.
write(fd,"12345");

예를 들어 위와 같은 동작을 하면 write가 되돌아오면 그 다음 시간에 디스크에 이 데이터를 쓰기 (리셋) 할 것이다. (따라서 시스템 호출은 디스크와 동기화되지 않는다.) 만약 이 기간에 다른 프로그램이 이 바이트를 읽으려 한다면, 직접 메모리 캐시 구역에 저장해서 읽는다.
이와 같이 디스크에서 읽는 경우, 디스크에서도 디스크 버퍼로 먼저 읽히고,read 호출은 여기서 데이터를 읽습니다.서열화된 파일 접근에 대해, 엔드코어는 필요하기 전에 이 파일의 다음 데이터를 버퍼에 빨리 읽을 수 있도록 미리 읽으려고 시도합니다. 이 디자인을 사용하면read () 와 write () 의 조작을 가속화할 수 있습니다.
linux의 내장 버퍼는 고정된 상위권이 없기 때문에 내장 버퍼는 가능한 한 많은 메모리를 분배할 것이다. 일반적으로 이것은 두 가지 요소에만 한정된다.사용 가능한 물리적 메모리 총량 및 기타 목적의 메모리 수요
2. 버퍼 크기가 입출력 시스템 호출에 미치는 영향
만약 버퍼가 없다면 우리는 다음과 같은 1000바이트의 읽기와 쓰기를 상상할 수 있다. 그러면 핵은 1000개의 디스크에 접근해야 한다. 모두가 알다시피 핵이 디스크에 접근하는 속도가 매우 느리다. 그러면 버퍼의 크기가 조작 시간에 얼마나 큰 영향을 미칠까?
다음 표는 linux 시스템 프로그래밍 매뉴얼에서 발췌한 것으로, 100M 파일을 복사하는 데 걸리는 시간을 서로 다른 크기의 캐시 구역을 설정함으로써 비교합니다
BUFFER_SIZE
총 사용 시간(s)
1
107.43
2
54.16
4
31.72
8
15.59
16
7.5
32
3.76
64
2.19
128
2.16
256
2.06
512
2.06
1024
2.05
4096
2.05
65536
2.06
위의 그림에서 버퍼 크기가 파일 복사 이벤트에 큰 영향을 미친다는 것을 알 수 있습니다.버퍼 크기가 4096일 때 거의 최우수에 달했고 이 값을 초과하면 효과가 현저하지 않다
3.stdio 라이브러리 버퍼
디스크를 조작할 때 큰 블록의 데이터를 버퍼링하여 시스템에서 C함수 라이브러리로 호출하는 입출력을 줄이는 것이 바로 이렇기 때문에 C표준 라이브러리 입출력을 사용하면 사용자가 버퍼를 스스로 처리할 필요가 전혀 없다
(1) 스튜디오 흐름의 버퍼 모드 설정
#include<stdio.h>
int setvbuf(FILE *stream,char *buf,int mode,ssize_t size);

setvbuf 함수를 호출하면 stdio 라이브러리의 버퍼 모드를 제어할 수 있습니다.매개 변수stream은 어떤 파일 흐름의 버퍼 모드를 수정해야 하는지 설명합니다.파라미터 buf가 NULL이 아닐 때stream의 버퍼 크기는size이고 버퍼 크기는 덤프에서 분배됩니다.buf는 NULL이고 버퍼에는 stdio가 기본적으로 할당되어 있습니다.매개 변수 모드가 버퍼 형식을 지정했습니다
mode 값
구체적 표현
_IONBF
입출력 버퍼 없음
_IOLBF
행 버퍼 입출력 사용
_IOFBF
전체 버퍼 I/O 사용
#include<stdio.h>
void setbuf(FILE *stream,char *buf);

.buf가 BULL일 경우 버퍼가 없음을 나타냅니다. 그렇지 않으면 buf 크기의 버퍼를 사용합니다.
(2) stdio의 버퍼 리셋
#include<stdio.h>
int fflush(FILE *stream);

매개 변수stream이 NULL이면 모든 stdio 버퍼를 새로 고칩니다
4. 파일 입출력을 제어하는 커널 버퍼
때때로 우리는 데이터베이스 로그 프로세스와 같은 내장 구역을 출력 파일로 강제로 리셋해야 한다. 계속 작업하기 전에 출력을 디스크에 진정으로 기록해야 한다
(1)fsync()
#include<unistd.h>
int fsync(int fd);

이 함수는 디스크 장치에 대한 전달이 완료되어야만 되돌아옵니다. 그렇지 않으면 막힙니다
(2)sync()
#include<unistd.h>
void sync(void);

sync () 호출은 파일과 새로운 정보를 포함하는 모든 내장 캐시 영역을 디스크로 리셋합니다
(3) open() 호출된 OSYNC 플래그
Open 호출 후 OSYNC 로고는 write () 호출할 때마다 자동으로 파일 데이터와 메타데이터를 디스크에 리셋합니다
O_SYNC 로고가 성능에 미치는 영향은 매우 큽니다. 아래는 linux 시스템 프로그래밍 매뉴얼에서 발췌한 것입니다
BUF_SIZE
O 없음SYNC(s)
O 있음SYNC(s)
1
1030
98.8
16
65.0
0.40
256
4.07
0.03
4096
0.34
0.03
5. 요약
파일 I/O 버퍼는 주로 stdio 라이브러리를 통해 사용자 데이터를 stdio 버퍼에 전송하는 것이다. 이 버퍼는 사용자 상태 메모리 구역에 위치하고 버퍼가 가득 차면 stdio는 write() 시스템 호출을 호출하여 데이터를 버퍼에 전송하고 일정한 시간 후에 디스크에서 디스크 조작을 시작하여 데이터를 디스크에 전송한다.

좋은 웹페이지 즐겨찾기