Registered Buffer의 커널 관리 방식과 성능

RIO 이전방식 부하 (IOCP등)


Send/WSASend 커널 동작 (부하)

오해한 부분 : RIO의 핵심은 “제로카피”가 아니라, 반복 I/O오버헤드를 줄여 효율을 올리는 것.

RIO는 버퍼등록/큐 기반으로 커널 경계 비용을 줄이는 API로, 내부 경로에서 항상 end-to-end 제로카피를 보장하는 것은 아니다.

RIO(Registered I/O) 모델


특징 : 버퍼 등록은 1회, I/O는 비용 없음

서버 초기화 시 단 1회:
RIORegisterBuffer(pBuffer, size)
│
├── ① 페이지 Lock → 영구 고정 (물리 메모리에 박아둠)
├── ② MDL 생성 → 커널이 캐싱
└── ③ VA→PA 변환 → 커널이 캐싱
│
└── ↓ RIO_BUFFERID 반환 (이 핸들 하나가 모든 것을 대표)

이후 매 I/O 시:
RIOSend() / RIOReceive()
│
└── "이미 등록된 BUFFERID의 offset/length 범위만 써"
    │
    ├── → 페이지 Lock 없음
    ├── → MDL 재생성 없음
    └── → 주소 변환 없음

핵심 요약


IOCP와 RIO의 결정적인 성능격차

1. 시스템 콜 횟수 (Syscall Count)

[IOCP 흐름]
유저 스레드
└─ WSASend()        → 시스템 콜 (1)  (커널 진입)
└─ WSARecv()        → 시스템 콜 (2)  (커널 진입)
└─ GetQueuedCompletionStatus() → 시스템 콜 (3) (완료 대기)