저는 Linux 기반 서버를 사용하여 멀티 플레이어 온라인 게임을 개발하는 프로그래머입니다. 우리는 우리 세계에 "인스턴스화 된"아키텍처를 사용합니다. 즉, 세계 지역에 입장하는 각 플레이어는 해당 지역의 사본을 얻어 파티원과 게임을하고 동일한 지역에서 플레이하는 다른 모든 플레이어와 독립적입니다.더 효율적으로 fork() 및 copy-on-write 메모리 공유 사용하기
내부적으로 우리는 각 인스턴스에 대해 별도의 프로세스를 사용합니다. 처음에는 각 인스턴스 프로세스가 시작되고 주어진 영역에 필요한 리소스 만로드하고 무작위 지형을 생성 한 다음 플레이어로부터 새로운 연결을 허용합니다. 인스턴스가 사용하는 메모리의 양은 일반적으로 자원과 엔티티가 포함 된 무작위로 생성 된 레벨을 포함하여 약 25MB였습니다.
인스턴스의 메모리 사용 공간을 줄이고 스폰 시간을 단축하기 위해 인스턴스가 필요할 수있는 모든 리소스를로드하는 단일 마스터 인스턴스를 만드는 방법으로 변경했습니다 (약 150MB 메모리)에 저장 한 다음 새 인스턴스가 필요할 때 fork() 함수를 사용하여 새 인스턴스를 생성하고 copy-on-write 메모리 공유를 사용하여 새 인스턴스가 "고유 한"데이터 세트의 메모리 만 필요로합니다. 임의로 생성 된 레벨과 각 인스턴스의 고유 한 데이터를 구성하는 엔티티의 공간은 약 3-4MB의 메모리입니다.
불행히도 메모리 공유가 제대로 작동하지 않는다고 생각합니다. 많은 메모리 페이지가 공유되지 않는 것처럼 보입니다.
처음에는 프리 프레임 인스턴스에서 더 많은 데이터 세트를로드 할 때 각 포크 된 인스턴스에 필요한 메모리가 다운되지만 결국 프리 포크에서 더 많은 에셋을로드하면 실제로 사용되는 데이터가 증가하는 변곡점이 있습니다. 각 포크 된 인스턴스.
우리가 미리 포크 데이터 세트의 약 80 메가를로드 한 다음 새로운 인스턴스가있는 가지고있는 최고의 결과는 나머지를로드 요구한다. 인스턴스 당 약 7-10 추가 메가와 80 메가 고정 비용이 발생합니다. 확실히 좋은 개선이지만 이론상 최고는 아닙니다.
I 전체 150 메가 데이터 세트하고 포크로드되면 각 갈래 인스턴스 메모리는 약 50 메가 이상 사용! 단순히 아무것도하지 않는 것보다 훨씬 더 심합니다.
제 질문은 프리 프레임 인스턴스에 모든 데이터 세트를로드하고 각 인스턴스의 메모리 풋 프린트로 인스턴스 데이터 당 최소 고유 집합 만 가져 오도록하려면 어떻게해야합니까?
은 여기 무슨 일이 일어나고 있는지에 관한 이론을 가지고 누군가가 이런 경우가 나를 위해 확인 도울 수있을 것인지 궁금 해서요.
malloc 무료 체인과 관련이 있다고 생각합니다. prefork 인스턴스의 각 메모리 페이지에는 메모리의 여유 공간이 남아 있습니다. 임의의 레벨 생성 중에 무언가가 페이지의 자유 지점 중 하나에 적합하게 할당되면 전체 페이지가 분기 된 프로세스로 복사됩니다.
Windows에서 대체 힙을 만들고 프로세스에서 사용하는 기본 힙을 변경할 수 있습니다. 이것이 가능하면 문제가 제거됩니다. 리눅스에서 그런 일을 할 수있는 방법이 있습니까? 내 수사는 당신이 할 수 없다는 것을 나타내는 것 같습니다.
또 다른 가능한 해결책은 어떻게 든 기존의 malloc 자유 체인을 삭제하여 이후의 호출을 위해 운영 체제의 새로운 메모리를 malloc에 할당하도록하는 것입니다. 필자는 malloc을 쉽게 구현할 수 있는지 살펴보기 위해 malloc을 시도했지만, 다소 복잡 할 것 같았다. 누구든지이 분야와 관련하여 아이디어가 있거나이 접근법을 어디서부터 시작해야할지 제안을 듣고 싶습니다.
마지막으로 누군가가 여기에서 잘못 될 수있는 것에 대한 다른 아이디어가 있다면, 나는 정말로 그걸 듣고 싶습니다. 고마워요!
큰 기존 코드베이스이기 때문에 malloc/new를 완전히 바이 패싱 할 수는 없으며, 모든 리소스 로더가이를 아주 행복하게 사용합니다. 나는이 접근법을 배제 할 의사가 없지만 가능하면 누군가 elses 메모리 할당자를 계속 사용하고 싶습니다. – Negs
@Negs 사용자 정의 할당자를 사용하거나 'malloc'을 도용 할 수 있습니다. 그러나 두 번째 단락을 읽으십시오. 젖소에 의지하지 말고 자신의'mmap'을하십시오. – cnicutar
그래도 사용자 정의 할당자를 작성해야하는데,이 방법을 사용할 수는 있지만 그렇게 할 필요가없는 해결책을 찾고 싶습니다. 아마도 기존의 malloc 주변에서 래퍼 접근 방식을 사용하여 아마도 내 필요를 용이하게 할 수 있을까요? – Negs