연구한 이야기/깊게 공부해보기
동기화객체 성능테스트
동기화객체 성능테스트 멀티스레드와 동기화 객체 멀티스레드 프로그래밍은 하나의 기능을 여러 스레드가 동일하게 실행하는 호모지니어스 방식과, 업무를 다르게 각자의 스레드로 분배하는 헤테로지니어스 방식으로 구분됩니다. 예를 들어, 게임 서버에서 길찾기 기능을 하나의 스레드로 분리하고, 네트워크 IO를 하나의 스레드로 분리한다면, 이는 헤테로지니어스 방식의 멀티스레드 설계입니다. 하지만, IOCP의 워커 스레드와 마찬가지로 하나의 동일한 로직을 수행하는 스레드가 여럿 있다면, 이는 호모지니어스 방식의 멀티스레드입니다. 이러한 멀티스레드 프로그래밍에서는 주의해야 할 점들이 생깁니다. 동기화 문제입니다. 가장 단순한 연산인 증감 연산마저도 CPU atomic하지 않기에, 수행 도중 context switching이..
IOCP 서버 코어 개발하기
IOCP 서버 코어 개발 IOCP 기반 서버 코어 개발하기 이 문서는 IOCP를 기반으로 한 서버 라이브러리 개발 과정을 담았습니다. IO Completion Port IO Completion Port란, Windows OS에서 입출력 완료 통지를 알려주는 방식을 의미합니다. 흔히 소켓 모델의 하나로서 이야기되고는 하지만, 엄밀히 말하면 이는 그저 Overlapped IO에서 입출력 결과를 통지하는 하나의 방법론일 뿐입니다. 소켓 통신 또한 네트워크를 통한 IO이기에, 이에 대한 입출력 완료 통지를 IOCP를 통해 받도록 할 수 있습니다. Overlapped IO와 비동기 Overlapped IO란, IO가 Overlapped (중첩) 된다는 뜻으로서, 하나의 스레드가 한번에 하나의 IO만을 처리하는 것..
패킷 직렬화버퍼
패킷 직렬화와 마샬링 네트워크간 통신이 이루어지기 위해서는, 레이어 7계층에서부터 보낼 데이터를 아래 층으로 요청하여 결국 1계층의 비트 스트림으로 변환되고, 이후 수신 때에도 비트 스트림으로부터 레이어 7계층의 의미있는 데이터로 해석해내는 과정이 필요합니다. 이러한 일련의 과정에서 ‘데이터를 바이트 스트림으로 변환하는 과정’을 ‘직렬화’라고 하며, 이를 포함하여 데이터의 메모리 구조를 저장이나 전송을 위해 적당한 자료형태로 변형하는 과정을 ‘마샬링’이라고 부르고 있습니다. 바이트 오더 바이트 오더, 바이트 순서는 OS가 내부적으로 데이터를 표현하는 방식을 의미하기에, 현재는 CPU 아키텍처에 따라 두 종류의 바이트 오더가 존재합니다. Little Endian이라고 불리는 방식은 데이터가 바이트 단위로 ..
메모리풀과 프리리스트
개요 메모리풀은 미리 메모리를 준비시키고 이를 재사용하게 함으로서 생성과 반환에 소모되는 시간을 없애는 기술입니다. 가상메모리 시스템에서도 4KB단위로 페이징하는 것이 메모리풀의 성격을 가지고 있다고 볼 수도 있겠습니다. 다양한 버킷 크기를 지원하는 메모리풀의 구현은 안전 장치가 더해질수록 기본 힙 관리자와 성능차이가 줄어들 것이므로, 이 프로젝트에서는 고정 크기의 객체 (오브젝트)에 대한 메모리풀을 도입하는 것으로 하겠습니다. 메모리풀과 프리리스트 메모리풀 메모리풀은 처음 초기화 시 지정된만큼 충분한 메모리 공간을 할당받아 관리를 시작합니다. 이 경우, 준비된 메모리를 할당받아 사용하고 반환하는 것은 성능 향상이 되지만, 만일 메모리풀이 부족할 경우 resize를 할 지, 이 오버헤드가 감당 가능한지 ..
TCP와 링버퍼
TCP와 L7 버퍼링 TCP와 UDP를 비교하였을 때, 개발 측면에서의 가장 큰 차이점은 UDP는 데이터그램 방식으로서 송신한 메시지가 정확한 크기로 상대방에게 전달되지만, TCP는 데이터 간 경계가 없이 스트림 방식으로 송수신된다는 점입니다. 이러한 특징으로 인하여 7계층에서 4계층 TCP 버퍼로부터 데이터를 읽어올 때, 메시지의 완전한 형태의 패킷으로 받아지지 않는 경우를 대비하기 위해 7계층에도 수신 버퍼가 필요합니다. 7계층에서 수신된 모든 네트워크 데이터를 버퍼링하고, 해당 데이터가 충분히 쌓이게 되어 읽을 수 있는 상태가 된다면 그 때 메시지를 읽어내어 버퍼에서 빼내는 방식을 사용해야 합니다. L7 버퍼의 필요성 수신 링버퍼는 TCP의 특성상 데이터의 경계가 없이 스트림으로 오는 수신 데이터를..
더 빠른 길찾기
고전적인 길찾기 방법, ASTAR 그래프 형태의 구조에서 목적지로의 경로를 찾는 방법에는 다익스트라, 벨만-포드 알고리즘 등이 존재합니다. 하지만 이러한 그래프 구조는 실제 MMORPG 게임서버 맵에서 적용하기 쉽지 않기에, 타일 구조로 맵을 변환시켜 길찾기를 시도하고는 합니다. 타일 구조에서의 길찾기 방식 중 가장 대표적이고, 유명하며 간단한 방식이 A-Star 길찾기입니다. 출발지로부터 연결된 모든 인접 노드를 통해 목적지로 탐색해나가며, 탐색하는 노드마다 가중치를 부여해 목적지로 가는 최단 경로를 찾아내는 방식입니다. ASTAR 구현 ASTAR 구현을 위해서는, 각 타일에 대한 ‘탐색한 정보’를 담을 노드 구조체와, 탐색했던 노드와 탐색할 노드를 담을 컨테이너 자료형 두 개가 필요합니다. struc..
레드블랙트리 구현 및 분석
개요 기본 이진트리와 레드블랙트리를 구현해보고, 시각화하여 확인할 수 있도록 합니다. 다른 컨테이너들과 성능을 비교해보고 게임 서버에서의 사용처를 분석합니다. 레드블랙트리 구현 이진탐색트리의 한계 이진탐색트리는 구현이 간편하지만, 다음 극명한 한계점들을 가지고 있습니다. 노드가 한쪽으로 쏠려서 관리될 수 있기에, 성능은 최악의 경우에 O(N)의 시간을 소모합니다. 이러한 경우 선형 탐색과 다를 바가 없기에, 기본 이진탐색트리를 사용하는 경우는 드뭅니다. 균형잡기 (밸런싱)과 회전 이러한 이진탐색트리의 한계를 극복하기 위해, 자체적으로 노드들의 높이를 맞출 수 있는 자가균형트리에서는 회전을 통해 노드간 밸런스를 맞춥니다. 코드와 주석이 문서 뒤에 위치합니다 레드블랙트리의 특징 레드블랙트리는 다음 네 가지의..