오해한 부분 : RIO의 핵심은 “제로카피”가 아니라, 반복 I/O오버헤드를 줄여 효율을 올리는 것.
RIO는 버퍼등록/큐 기반으로 커널 경계 비용을 줄이는 API로, 내부 경로에서 항상 end-to-end 제로카피를 보장하는 것은 아니다.
특징 : 버퍼 등록은 1회, I/O는 비용 없음
서버 초기화 시 단 1회:
RIORegisterBuffer(pBuffer, size)
│
├── ① 페이지 Lock → 영구 고정 (물리 메모리에 박아둠)
├── ② MDL 생성 → 커널이 캐싱
└── ③ VA→PA 변환 → 커널이 캐싱
│
└── ↓ RIO_BUFFERID 반환 (이 핸들 하나가 모든 것을 대표)
이후 매 I/O 시:
RIOSend() / RIOReceive()
│
└── "이미 등록된 BUFFERID의 offset/length 범위만 써"
│
├── → 페이지 Lock 없음
├── → MDL 재생성 없음
└── → 주소 변환 없음
핵심 요약
[IOCP 흐름]
유저 스레드
└─ WSASend() → 시스템 콜 (1) (커널 진입)
└─ WSARecv() → 시스템 콜 (2) (커널 진입)
└─ GetQueuedCompletionStatus() → 시스템 콜 (3) (완료 대기)