IOCP는 IO operation 마다 버퍼 영역에 대한 page-lock/unlock이 필요하고, 이는 많은 CPU 연산을 필요로 한다.
(하나의 IO operation 마다 시스템콜 호출, 유저-커널모드 switching 발생)
Zero-recv같은 우회방법으로 page locking을 회피 했었다.
이런 문제점을 해결하기 위해 IO에 사용할 물리메모리를 고정시켜두고 사용하는 방법으로 RIO가 등장하며 매 IO마다 page-lock/unlock이 필요 없어졌다.
단점으로는 메모리를 미리 선점하는 형식이기 때문에 미사용 하는 메모리의 양이 존재한다.
IOCP와의 차이점은 IOCP의 경우엔 그저 해당 핸들로 Post, Get 전부 Thread Safe하게 사용할 수 있었지만, RIO의 Request Queue (RQ)와 Completion Queue (CQ)가 Thread Safe 하지 않다는 것이다.
그래서 주로 사용하는 방법이 TCP의 세션을 특정 스레드에 고정시켜 사용하는 것이다.
State Full 서버라면 특정 기준(맵 등)으로 스레드를 나누고 해당 스레드에 유저를 넣어두면 별 문제 없을 듯 하다.
+ 소켓의 Send, Recv, Close 함수들을 1개의 lock으로 묶어서 사용하자.
UDP라면 Connection을 유지할 필요가 없기 때문에 더 쉽게 사용할 수 있을 듯 하다.
여기에 RIO가 물리 메모리를 사용한다는 점을 NUMA와 함께 고려한다면, CPU와 가까운 큰 메모리 블럭을 할당받고, TCP 세션별로 나눠서 사용하는 것도 생각해볼 수 있다.
그리고 Hyper Thread 환경에서 1개의 코어에서 2개의 스레드를 돌리는 것 보단 Affinity를 조절해 1코어에서 1스레드를 사용하는 것이 성능상의 이점을 가지고 갈 수 있다고 한다.
아무래도 스레드별 lock과 메모리 이슈가 아닐까..? 내용 보강이 필요하다
https://jacking.tistory.com/1177
https://www.slideshare.net/sm9kr/windows-registered-io-rio
http://www.serverframework.com/asynchronousevents/rio/
https://github.com/unicomp21/RIO.lib
https://github.com/zeliard/RIOTcpServer/tree/RioWithIocp
관련 논문
http://www.koreascience.kr/article/JAKO202007650437076.pdf
'서버 > RIO' 카테고리의 다른 글
RIO Function table 구조체 (0) | 2022.10.02 |
---|