|
Buffered I/O 와 Non-Buffered I/O를 이야기 하시는 것 같군요.
Buffered I/O 함수들은, 버퍼가 가득 차거나, 별도의 END_OF_LINE으로써의 개행코드,
END_OF_FILE(EOF) 등의 특정 심볼에 반응하여 버퍼된 데이타를 Update하는 식,
혹은 그밖에 Half Duplex 구조일 경우 입력스트림과 출력스트림을 스위칭 해야 할 때 등의 경우
입출력을 일단락 짓도록 설계되어 있기 때문에, 당장 입출력을 보내고 싶을 때 fflush 함수를 사용하는 것이죠.
GDI 함수들 중의 Update 와 Invalidate 의 경우와도 유사한 형식이라 볼 수 있습니다.
반면, 저수준 입출력이라고 말씀하신 open, close, lseek, read, write 등의 함수들은
C/C++ 의 Library Function(대부분 Buffered I/O) 이 아닌
운영체제가 제공해 주는 함수(API)로써, 의도 되지 않은 버퍼링이나 메모리 낭비를 줄이기 위해
즉시 반응하게 되어 있습니다.
조금 여담이지만 getc, putc의 경우는 마치 API함수인것 처럼 생겼지만, fgetc, fputc의 매크로 형식입니다.
단지 Buffered I/O 함수명들과 Non-Buffered I/O 함수명들이 pair를 이루는것 처럼 보이기 위한 것이죠.
반면, fflush의 경우는 Non-buffered 의 경우 flushing 할 일이 없으니 당연히 존재할 필요가 없구요.
HDD 의 구조를 Block Device 라고 합니다.
그 이유는, 한번에 1byte씩 I/O할 수 있는 구조가 아니라(Flash Memory도 Block Device죠),
512byte씩 혹은 그의 배수를 최소 단위로 I/O할 수 있는 Device이기 때문입니다.
코딩의 편의를 위해 한 바이트씩 읽을 필요가 있어 getc / putc / fgetc / fputc 등의 함수를
구현해 놓긴 했지만,
Non-buffered인 read 함수를 이용해 1byte씩 읽는다 칩시다. (혹은 그걸 getc 라고 매크로 해 놓고 사용했다 칩시다)
그런 경우, 연속한 100byte를 1byte씩 읽어오기 위해서는
512바이트를 하드에서 읽어오고 1바이트를 취한 다음 나머진 버리고
다시 512바이트를 하드에서 읽어 또 1바이트를 버리는 식이니 엄청난 낭비이겠죠?
그래서 파일 입출력에 Buffered I/O 함수들이 구현된 것이고,
실제 fgetc(getc) 등을 연속적으로 호출 할 때, 하드디스크에서 매번 읽어오는게 아니라,
한꺼번에 하드디스크의 Block 크기만큼 읽어놓은 메모리(버퍼)에서 1바이트씩 가지고 오니
효율적이고 빠른 I/O가 가능하게 되는겁니다.
CPU와 Memory는 Local Bus 형태로 고속으로 입출력이 가능하게 되어 있습니다.
반대로, 주변 장치들의 I/O는 CPU점유율이 높고(당연하게도 I/O명령은 기본적으로 CPU가 내리는데다,
Mainboard 의 주파수는 CPU의 주파수 보다 훨씬 느리기때문에 쓸데없이 CPU가 기다려야 하죠)
CPU를 경유해 다시 Memory로 전송되어야 하는 경우가 태반이라 잦은 외부 I/O는 시스템을 느려지게 합니다.
이를 극복하기 위해 크게 Multi-programming, DMA Channel 같은 기술을 사용하고 있지만,
DMA(Direct Memory Access) Channel 방식을 지원하는 장치는 많지 않습니다.
이는 CPU를 거치지 않고 메모리에 확보된 영역에 외부 I/O들이 바로 써 넣는 기법이므로,
별도의 프로토콜을 가져야 함이죠.
정리하자면,
버퍼 관리를 멋지게 해 낼 자신이 있다면, 저수준 함수를 사용해 별도의 고수준 함수들을 만들어도 좋습니다.
각각의 외부 H/W I/O들에 대한 배경지식이 부족하여 잘 해 낼 자신이 없다면,
잘 만들어진 fopen, fclose, fread, fwrite, fseek, fgetc, fputc 등의 buffered I/O 함수를 쓰는게
성능에 도움이 되는 것입니다.
파일처리론 책을 숙독하시면 쉽게 알 수 있는 이야기들이었군요.
그럼 이만.
김상면 님이 쓰신 글 :
: 고 수준의 파일 입출력은 fflush함수로 입출력을 동기화 하는 걸로 알고 있는데...
: 저수준의 파일 입출력은 이런 동기화가 필요 없나요? 왜 flush가 없징....
:
: 고수님의 답을 구합니다.
: 그럼
|