C#으로 게임서버를 개발한다면?

c# 서버 제작하시는 분 있으신가요?

게임 코디에 올라온 c# 서버 제작하시는 분 있으신가요?라는 질문에 대해 나름대로 답변을 하고자 한다.

구글 검색, GPG 검색으로 c# 개발에 대해 부정적인 시각이 매우 많네요.
그런데 요즘 구인 글 보면 c# 서버 개발 가능자란 문구가 좀 보이는데요…
아직까지 캐주얼 게임에만 적용된 C#서버만 보였는데,
MMORPG 개발사인데 C#서버 개발 가능자를 뽑긴 하던데…
요즘엔 MMORPG에 C#서버로 돌리나요?
업계 동향 보니깐 아예 c#으로 가는 팀도 많아 보이던데….
혹시 경험 및 사례 있으시면 조금 공유 부탁 드려봅니다.

질문과 답변 형식으로 궁금증을 해소하는 편이 읽는 이가 이해하기에 나을 듯 싶다.

참고로 굳이 C#을 고려한 걸 보면 C#을 도입했을 때의 장점은 분명히 알리라 믿고 이 글에서는 성능 문제에만 초점을 맞춘다.

C#이 느리다던데요?

무엇과 비교하는냐에 달렸다. C/C++과 비교하면 느리다. 그런데 얼마나?

C# versus C++ versus Java performance comparison에서 가져온 이 자료에 따르면 Windows에서 C++은 C#보다 단지 15%가 빠를 뿐이다. 2009년도에 성능 차이가 이 정도였으니 현재는 격차가 더 적을 것이다. 물론 벤치마크의 방식과 샘플 데이터에 따라 결과는 달라진다. 하지만 대부분의 벤치마크에서 비슷한 수치를 보고한다.

그런데 왜 사람들은 C#이 느리다고 하죠?

C# 응용프로그램이 느리다고 느끼는 이유는 몇 가지 있다.

Just-in-time 컴파일

.NET Framework 는 JIT 컴파일을 한다. 여러분이 Visual Studio 에서 C#을 컴파일하면 바이너리 코드가 아닌 VM(가상머신) 언어로 결과가 나올 뿐이다. 나중에 응용프로그램을 실행할 때 .NET Framework 런타임이 VM 언어를 다시 네이티브 바이너리로 컴파일한다.

이런 까닭에 응용프로그램의 초기 구동시 반응이 느릴 수밖에 없다. 대부분의 프로그래머는 코드를 몇 줄 고치고 프로그램을 실행하고 닫는다. 이런 과정을 반복하기 때문에 장시간 운영되는 라이브 환경에서 나오는 성능보다 훨씬 낮은 체감 성능을 느낀다.

.NET Framework 에는 C# 코드를 바로 네이티브 코드로 컴파일하는 도구가 있긴 하다. 하지만 이런 도구를 사용하면 JIT가 제공하는 최적화를 놓치게 된다. 이러한 도구는 구동 시간이 중요한 클라이언트에 써야지 전체 처리량(Throughput)이 중요한 서버에 쓸 게 아니다.

가비지 컬렉션 방식

.NET Framework의 메모리 할당 방식은 간단히 말해 스택 할당이다. 따라서 할당 속도는 C++ 보다 빠르다. 물론 C++ 처럼 메모리 할당 전략을 프로그래머가 마음껏 바꿀 재량권은 상당히 박탈당한다.

빠른 할당에 비해 해제는 상당히 느린 편이다. 메모리가 부족하다 싶을 때 가비지 콜렉터가 한꺼번에 정리하기 때문이다. .NET Framework 의 런타임은 전체 처리량에 맞춰 최적화했다. 따라서 이러한 전략은 웹 서버와 같이 일시적인 느려짐이 크게 문제되지 않는 곳에 매우 적합하다. .NET Framework 초기에 ASP .NET 에 초점을 맞춰 마케팅이 이뤄진 점만 봐도 이러한 설계 철학이 이해가 된다.

따라서 C# 으로 서버를 개발한다면 소위 말하는 렉이 주기적으로 발생한다. 렉이 가끔 발생해도 문제되지 않는 서버에 쓰는 게 좋다. 렉이 발생해도 플레이어가 크게 불평하지 않는 캐주얼 게임이 아니라면 게임서버보다는 캐시서버 등에 적합하다고 보면 된다.

메모리 부족

같은 양의 데이터를 처리한다고 볼 때 C# 응용프로그램이 메모리 소모가 심하다. 몇 가지 이유가 있지만 무엇보다 가비지 콜렉션을 최후까지 미루는 탓도 크다.

이렇다 보니 메모리가 부족한 환경에서는 가비지 콜렉션을 자주 해야 한다. 그뿐 아니라 스왑도 자주 발생한다. I/O 가 서버 성능에 가장 큰 영향을 미치는 요소 중 하나라는 점을 생각해야 한다.

단, 라이브 환경에서는 값싼 메모리를 마구 투입하면 되므로 큰 문제가 되지 않을 수도 있다.

참고로 .NET Framework 는 COM 을 통해 메모리 할당 전략을 어느 정도 바꿀 수 있다. 다만 해제 전략과 관련된 어떠한 API 도 제공하지 않는다.

C# 으로 구현한 상용 게임이 있어요?

있다. 마비노기 영웅전! 그 외에도 개발 중인 MMORPG 도 있다. 단, 프로젝트마다 아키텍처와 문제해결 방식이 다르다. 고민 많이 해야 한다.

나쁘지 않은데?

그렇게 좋다면 왜 C# 서버를 도입한 곳이 별로 없죠?

렉 문제와 설계의 어려움

앞서 말한 렉 문제가 게임 플레이에 크게 악영향을 주는 경우가 있다. 각 서버군 별로 나눠서 필요한 곳에만 C#을 적용해도 된다. 하지만 여러 개의 프로그래밍 언어를 개발팀이 익히고 유지보수해야 하는 문제가 있다. 또한 어떻게 아키텍처를 설계해야 C# 도입의 장점을 최대한 살리고 그 단점을 최소로 줄일 수 있는지 파악하기 힘들다.

느리다

어라, 방금 전까지 C#의 성능이 훌륭하다고 말하지 않았나? 아니, 그건 오해다. 15%? 작다면 작지만 어떤 경우에는 크다. 그게 핵심 엔진 코드라면 치명적일 수도 있다. 대체로 이러한 성능 차이는 분산 서비스로 설계하면 문제가 되지 않지만 단일 게임 서버에 하는 일이 몰린다면 심각한 문제가 야기될 가능성이 있다.

설계의 유연성이 부족하다

C++ 과 같은 네이티브 프로그래밍 환경이 주는 최대 장점은 설계의 유연성이다. 메모리 할당 및 해제 전략을 내 취미대로 고친다거나 무잠금 알고리즘을 적용한다던가(C#에서도 가능하지만, 그냥 해보면 안다) 초고성능을 추구하는 이에게 C# 환경은 답답한 면이 많다.

결론

여기까지 경험담을 정리했다. 잘 알고 잘 알아서 설계해서 알차게 살아보자. 어차피 내가 여러분의 프로젝트 책임자도 아니니 여기서부턴 나도 모르겠다.

급소 가격

Advertisements

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu