CS

표준 I/O 라이브러리의 등장 배경: 시스템 콜 성능 최적화

컴공오지마라 2024. 12. 8. 18:22

1. 서론

시스템 프로그래밍 수업을 통해 표준 I/O 라이브러리의 등장 배경을 학습하게 되었다. 이는 시스템 콜을 직접적으로 사용할 때 발생하는 성능 저하를 개선하기 위함이다. 이 문제의 원인을 깊이 이해하면 데이터베이스 등 다양한 I/O 작업과 관련된 코드를 작성할때 도움이 될 것 같아 정리를 하게 되었다.

2. 시스템 콜을 직접 사용할때 문제

2.1 Alignment 문제

Alignment 문제는 운영체제가 파일을 Block 단위로 I/O하기 때문에 발생하는 문제이다. 대부분의 파일 시스템과 디스크는 블록(Block) 단위로 데이터를 읽고 쓰며, 그 단위는4KB 또는 그 배수이다. 즉 프로그래머가 임의의 버퍼에 read 혹은 write 하라는 코드를 작성하면 이 버퍼의 시작 주소 및 크기가 Block의 시작주소 및 크기의 배수가 되는지 여부에따라 성능이 달라지게 된다.

 

예시

  • 블록 크기가 4KB인 디스크에서 2KB만 읽는 경우, 시스템은 4KB를 읽은 후 필요한 2KB만 반환한다.
  • 즉 데이터 읽기가 여러 블록에 걸쳐져 있으면 비효율적으로 작동하게 된다.

2.2 시스템 콜 오버헤드 문제

시스템 콜은 결국 커널모드로 진입해서 실행되기 때문에 유지모드에서 커널모드로 변환하는 Context switch 가 발생하게 된다. 따라서 시스템 콜이 많아질수록 컨텍스트 스위치 비용도 커지게 된다. 즉 동일한 데이터를 읽더라도 어떤 방식으로 읽느냐에 따라 성능이 달라지게 된다.

 

예시

  • 비효율적인 시스템 콜 호출방식
    • 1바이트씩 데이터를 1024번 읽는 경우, 1024 번의 Context switch 오버헤드 발생
  • 효율적 시스템 콜 콜 호출방시
    • 1024바이트를 한 번에 읽으면 시스템 콜이 1번만 수행되므로 오버헤드를 대폭 줄일 수 있다.

3. User-buffered I/O의 등장

File I/O를 한다는 의미는 운영체제에게 디스크에 파일의 읽기, 쓰기 요청을 보내는 것이고 반드시 시스템 콜을 사용해야한다. 그런데, 앞서 살펴본 정렬 및 시스템 콜 횟수 문제를 개선하고 성능을 최적화하기 위해 표준 입출력 라이브러리(STD I/O)이 등장하게 되었다.

3.1 표준입출력(STD I/O) 라이브러리의 구조 및 동작원리

응용프로그램이 시스템 콜을 직접 호출하는게 아니라, 해당 라이브러리가 사용자의 I/O 요청을 버퍼링하고 있다가 한번에 OS에게 요청하는 식으로 동작한다. 이 버퍼 내부에서 라이브러리가 Aligment를 조정하고 시스템 콜의 사용횟수를 최적화 한다. 또한, OS 에서 Buffering 하는 것은 OS가 write 시스템콜을 요청 받을때마다 디스크에 바로 쓰는 것이 아니라, 버퍼에 저장해두고 한번에 write하는 것을 의미한다.

User-buffered I/O 동작 과정

3.2 과연 항상 성능이 좋을까?

Buffering 이라는것은 결과적으로 File I/O의 시스템 콜 호출을 지연하게 된다. 그런데, 이 I/O 작업이 끝나야만 다음 작업이 진행되는 경우 전체 작업 종료시간이 길어지게 되므로 오히려 성능에 악영향을 미치게된다.

 

4. 결론

오늘 살펴본 내용은 기본적인 내용이지만, I/O 최적화에 대한 이해는 데이터베이스 시스템의 파일 접근, 버퍼 캐싱, 로그 쓰기, 인덱스 최적화 등에서 중요하다. 잘 기억해두도록 하자.