TCP 서버를 작성할 때, IOCP(I/O Completion Port)라는 용어를 흔히 접하게 됩니다. IOCP는 대규모 동시 연결(수천~수만 소켓)을 효율적으로 처리하기 위해 윈도우 운영체제가 제공하는 고성능 비동기 I/O 모델인데요, 이 글에서는 IOCP가 가상 메모리(Virtual Memory)와 결합하여 어떻게 고성능을 달성하는지 살펴보겠습니다.
1. IOCP의 기본 개념
- IOCP(Completion Port)
- 윈도우 커널 레벨에서 네트워크/파일 I/O 완료 시점을 통지하는 메커니즘이자 큐(Queue)입니다.
- 소켓(혹은 파일 핸들)을 IOCP에 등록해두면, 해당 핸들에 대한 I/O가 비동기로 진행되고, I/O 완료 시 IOCP 큐에 “완료 알림 패킷”이 쌓입니다.
- 스레드 풀
- 애플리케이션은 IOCP에 연결된 스레드들(Worker Threads)을 미리 생성합니다.
- 이 스레드들이 GetQueuedCompletionStatus로 큐에서 “누가 I/O를 끝냈는지” 꺼내 후속 로직을 처리합니다.
결과적으로, CPU가 놀지 않고 여러 클라이언트를 동시에 처리할 수 있으면서, 불필요한 스레드를 무한정 만들지 않아도 됩니다.
2. 네트워크 I/O와 가상 메모리의 연결고리
2.1 가상 메모리(Virtual Memory)
- 프로세스가 메모리를 사용하면, 실제로는 물리 메모리(RAM)의 일부분만 매핑하여 사용합니다.
- 윈도우 OS는 가상 메모리 페이징(Paging)을 통해 “애플리케이션이 요청한 버퍼를 어느 물리 페이지에 둘지” 결정하고, 필요 시 락(Lock)도 걸어줍니다.
2.2 Overlapped I/O 요청 시 메모리 Lock
- “이 소켓으로 데이터를 보낸다(WSASend)” 혹은 “파일에 쓴다(WriteFileOverlapped)”는 순간, OS는 해당 가상 주소 범위를 **물리 메모리에 고정(Lock)**합니다.
- 왜? 실제 네트워크/디스크 I/O 시, 장치 드라이버가 DMA(Direct Memory Access) 등으로 해당 메모리에 직접 접근해야 하므로, OS가 이 버퍼 페이지가 중간에 스왑아웃되지 않도록 보호.
- I/O가 완료되면 OS는 언락(Unlock)하여 페이징을 자유롭게 가능하게 합니다.
3. IOCP가 “빠른” 이유
- OS가 관리하는 쓰레드 풀
- 수백 개 소켓이 있어도, 동시에 실제 I/O를 처리 중인 소켓이 10개라면 10개 워커 스레드만 운영.
- 불필요한 컨텍스트 스위칭 최소화, CPU 사용률 효율 극대화.
- 가상 메모리 Lock/Unlock
- OS가 DMA를 위해 “이 버퍼 페이지는 건드리지 말아야 한다”는 잠금(Lock)을 자동으로 처리.
- I/O가 끝나면 Unlock. 이 과정에서 불필요 복사가 줄어듦.
- 비동기 모델
- I/O가 끝날 때까지 스레드가 블로킹되지 않음.
- CPU와 I/O를 병렬로 활용: CPU는 다른 로직을 계속 진행, I/O는 OS 내에서만 대기. I/O 완료 시점에만 스레드가 깨어남.
- 프로세스-커널 간 전환 최적화
- I/O 요청 -> 커널 내부 큐 -> 완료 -> IOCP 큐.
- 중간에 유저모드/커널모드 전환이 필요할 때, IOCP 방식으로 최소화해 놨다는 점이 성능의 큰 이점.
4. 요약 & 결론
- 가상 메모리와 IOCP가 결합된 이유:
- 네트워크로 데이터를 “주고받을” 때, OS는 해당 버퍼가 물리 메모리에 언제든 접근 가능해야 하므로, 페이지를 Lock.
- IOCP는 “이 I/O가 끝났어요”라는 사실을 한 큐(Completion Port)에 모아 두고, 워커 스레드만큼만 처리하므로 스레드 폭발 방지.
- 진정한 고성능:
- 운영체제가 I/O 스케줄링, 스레드 관리, 메모리 페이지 관리까지 다 해주므로, 애플리케이션은 최소한의 자원만으로 대규모 동시 접속이나 다중 파일 I/O를 처리 가능.
- 개발자에게 주어진 편의:
- I/O 완료를 “감지”하는 로직을 OS가 맡아주고, 워커 스레드가 GetQueuedCompletionStatus 한 번으로 처리.
- 그 뒤 가상메모리에 있는 버퍼를 프로세스 레벨에서 가공하면 됨.
'프로그래밍 > 소켓 프로그래밍 입문' 카테고리의 다른 글
IOCP 예제로 살펴보는 서버 설계 (0) | 2025.02.03 |
---|---|
왜 IOCP는 빠를까? 운영체제가 직접 관리하는 비동기 I/O의 힘 (0) | 2025.02.03 |
APC(Asynchronous Procedure Call) 알아보기 (0) | 2025.01.25 |
Windows 비동기 I/O의 두가지 방식, 이벤트와 콜백 (0) | 2025.01.25 |
콜백 기반 비동기 파일 I/O: 내부 동작 상세 (0) | 2025.01.24 |