Project Dark Star 그 후는?

작년 2월에 Sun Microsystems (이제는 Oracle) 에서 개발하던 Java 기반 게임 서버 프레임워크인 Project Dark Star가 접히고, 오픈 소스 프로젝트로 fork 했다는 얘길 했다.

현재 상황은 대략 망해가는 프로젝트인 것 같다.

마지막 stable version이 작년 12월에 릴리즈. 다운로드 수는 누적으로 70회;

마지막에 등록된 티켓(trac issue)이 올해 2월.

위키 최종 편집 시간이 6월[1] 포럼에만 활동이 약간 있는 정도. 이 정도면 거의 활동없는 프로젝트라고 봐야하나?

(실질적으로) 사용하는 곳이 없고 / 개발 팀도 응집되지 않은 듯 하고 (커밋한 사람 수를 보면…) / 앞으로 비전이 있는 프로젝트는 못 될듯 하다.

  1. 그 이전에 올해 들어와서 수정된 페이지가 6개 , 그리고 각각 1번씩만 수정 []

Project DarkStar 는 왜 실패했을까?

1. 게임 서버는 게임 제작 기간의 임계 경로(critical path)가 아니다

게임 서버는 대부분의 경우 “게임 제작 시작”과 동시에 작성되기 시작하는 경우는 거의 없다. 그래서 엔진을 사서 얻을 수 있는 이익 중 하나인 “시간 단축”으로 인한 효과가 적거나 없다. 물론 상대적으로 안정화된 코드 베이스를 빨리 얻을 수 있다는 이점은 존재 한다.

2. 게임 서버 구조에 대한 컨센서스가 없다.

게임 클라이언트는 각 모듈들 – 게임 로직, 렌더링, AI, … – 이 어느 정도 잘 분해되어 있다 – 적어도 그런 종류의 고민이 많이 끝난 상태다. 하지만 서버의 경우 게임 로직과 게임 서버 자체의 구동을 위한 아랫 단의 구분이 성능 저하없이 잘 이루어져 있는 경우가 드물다. 그래서 이런 서버용 게임 엔진은 시장에 나와 있는 예가 거의 없다. 내가 아는 범위 내에서는 DarkStar 프로젝트와, BigWorld Technology의 BigWorld Server 정도 밖에 없다. 그리고 이 범위 내에서, 상업적으로 충분한 성공을 거둔 게임(eg: 연간 1m USD 이상의 매출)은 없다.

그리고 각 프로젝트마다 실제 서버 구조 차이는 꽤나 컸다 – 내가 본 사용 서버 코드만 4개가 넘는데, 각자 다른 구조를 차용하고 있고, 기본적인 도구 수준에서나 같은 모습을 볼 수 있다. 하지만 DarkStar 는 일단 단일 구조로 나왔고, 커스터마이징이 가능하긴하지만 전체 구현 자체는 MMORPG 를 노린 것으로 보인다. 그렇기에 충분히 큰 시장을 가지지 못했다고 생각된다.

3. Java 사용의 문제

* Java GC가 신뢰할 정도로 빠른가? 분명히 Java는 서버 어플리케이션의 throughput 면에서는 만족할 만한 성능을 내고 있고, 이런 분야 – 각종 트랜잭션 기반 금융 업무, 웹 페이지 렌더링 … – 에서는 거대한 시장을 이끌고 있다.

하지만 반응 속도 면에서, 최소한 일정 수준 이상의 반응 속도가 필수적인 게임 서버에서도 이게 보장되는가?[1]  게임 서버에 가장 많은 부하가 걸릴 시간 – 메모리가 가장 모자라서 GC가 강제화라도 되어야할 시점 – 에 GC가 “한꺼번에” 일어나면 반응성의 문제가 생길 수 밖에 없다.

이건 약간 샛길로 새는 얘긴데, GC 문제는 C#에서도 역시 나타날 수 있다. 최근 런칭한 마비노기 영웅전 서버가 어느 정도 예측가능한 주기(<1일)로 비정기 점검(…을 가장한 서버 셧다운 넘기기)하는게 GC문제가 아닐까 의심 중이다. GC로 메모리가 모자라면 아주 일정한 수순을 거쳐서 서버가 죽게 된다.

1. GC로 반응(지연) 시간 증가

2. 큐에 작업이 쌓임

3. 더욱더 메모리가 필요해져서 GC 가 필요해짐

4. 악순환 시작. 실제 작업 로드를 내리는데 CPU가 사용되는게 아니라 GC에 들어감

5. 서버 사망

* 예전에 Rica 가 언급했던 서버/클라이언트 코드 공유 문제. 코드 생성기로 “우회”할 수는 있지만, 서버/클라이언트 코드 공유로 시스템 전체에서 중복을 제거하는 것도 무시못할 부분인데, 이 부분에서는 Java로 게임 클라이언트를 짜는게 거의 불가능한 상황[2] 을 생각하면 좀 암울하다.

* Java 나 C# 류의 언어는 확실히 생산성이 높다. http://www.codinghorror.com/blog/archives/000299.html 참고. 하지만 여기서 말하는 “Write his own” 항들을 게임 서버에서는 적어도 현재로는 필요하기에 사실상 다 하고 있다. 혹은 게임 서버/서버 용 라이브러리가 있거나..

4. Java 가 새 하드웨어 기술을 잘 따라잡고는 있는가?

적어도 게임 쪽에서는 아니라고 생각한다. 게임 서버는 그렇게 “현재의 기술”만 가지고 만들어지질 않는다. 한 예로 DarkStar 가 타겟으로 잡았던 MMO 시장의 한 게임을 들어보자. EVE Online 이라는 게임이 있는데, 이 게임의 서버 구조는 어느 정도 알려져 있다 (참조: EVE Online’s Server Model)

이 게임은 서버 군(혹은 shard 란 명칭으로 흔히 부르는 그것)이라는 개념이 없다. 모든 사용자는 “하나의 논리적인 서버”에 들어가는 형태다. 이걸 가능하게 한 기술은 InfiniBand 라고 부르는 네트웍 기술덕인데, CPU 버스 수준의 통신 속도+지연 시간을 보장하는 네트웍 장치다(다만 point-to-point). 이런 상대적으로 low-level 한 기술을 나오는 즉시 사용하기에는 Java 언어 자체의 변경 속도가 느리다. 그렇다고 이걸 C/C++ 로 만든 드라이버를 작성하고, 이걸 DarkStar 같은 녀석 밑단에 JNI 연결하기엔 배보다 배꼽이 커질 것 같다. 게다가 이쯤 되면 프로그래밍 모델이 우리가 흔히 보는 UMA가 아니라 NUMA 모델에 가까워진다. 그것도 non-cc NUMA… Java는 아직 NUMA 에서 GC 구현조차 실험적 상태(experimental) 이다.

또다른 예로, 32bit –> 64 bit 넘어가던 시절에 만들어진 모 게임이 있다. 이 게임의 경우 64bit 운영체제가 시장에 나올 즈음을 타겟팅해서 작성되었는데, 출시가 늦어지면서(…), .dll 의 메모리 모델이 좀 다른 점을 이용해서, 공유 메모리 비슷한 형태로(…) 32bit 응용 프로그램이 쓸 수 있는 물리 메모리보다 더 많은 물리 메모리를 쓸 수 있게 수정해서 출시했다고 한다.[3] 이런 low-level 한 시스템 프로그래밍을 DarkStar 같은데 연동하는건 절대로 쉬운 일이 아닐 거다.

물론 Java 가 새 기술을 따라잡으면, Java codebase 전체가 쉽게 이동한다는 장점은 있다. 그렇지만 Java 의 현재 가장 큰 시장은 게임 서버가 아니기에, 이 쪽으로의 이동이 빠를리는 없다 – 적어도 현재 시점에선 그렇게 보인다.

5. 이식성 문제나 하드웨어 호환성 문제는 서버 프로그래밍에서는 큰 이슈가 아니다

타겟 하드웨어와 타겟 OS를 정해놓고 작업할 수 있기에, Java 의 장점이라는 이식성/호환성 문제는 아예 이슈거리가 되질 않는다. 오히려 타겟 하드웨어에 맞는 최적화를 “손 쉽게” 쓸 수 없는 Java 의 문제가 생긴다.

6. DarkStar 는 모든걸 만들어야 했다

DarkStar 의 실패 원인 중 하나는, DarkStar 의 “기능”으로 소개한 것 중 중요한 것들은 3rd party library로 있는 애들이 많다는 거다. 혹은, 시장이 될만한 MMOG 제작사들이 이미 인-하우스 툴이 갖춰졌을 시점이라는 것.

DISCLAIMER: 이 글은 rein 의 개인적인 견해이며, 소속 기관 어디와의 연관성도 없음을 밝혀둔다. 또한 이 글의 각 사실 관계에 관해서는 현재 알고 있는 바에만 기초했으며, 이걸 사용해서 얻어지는 직/간접적인 결과에 대해서는 rein은 아무런 책임이 없음을 밝힌다.

  1. 물론 클라이언트에서 이런 반응 속도를 속이기 위한 각종 테크닉을 사용한다. 사용자의 입력에 대한 일단의 액션을 보여주고, 최종적인 결과 처리는 서버의 판단 후에 반영된다거나(이럼 RTT 만큼의 시간은 걸린다). []
  2. Java 용 게임 클라이언트 라이브러리의 수는 C++용 게임 클라이언트 라이브러리 수와 order-of-magnitude 의 차이가 난다. 질 적인 면에서는 그 성숙도에서 엄청난 차이가 날 게 틀림이 없음에야… []
  3. 이건 PAE 같은 CPU 확장 기능을 이용하면 32 bit OS 라도 16GiB~32GiB 수준의 메모리를 쓸 수 있어서 가능한 것 []

Project Dark Star 개발 중단 및 오픈 소스화

Sun Microsystems 의 Java 기반 MMORPG 서버 프로젝트인 Project Dark Star 가 개발 중단되고, github 와 구글 포럼으로 소스 저장소/포럼을 이전한다고 공지되었다 – via gamedev.net

Project Dark Star 의 포럼 공지에 따르면,

Today is a difficult day for all of us associated with Project Darkstar. Regretfully, we must inform our community members that Sun Labs engineering effort is no longer being applied to Darkstar development. You will hear from the individual engineers about what this means for them, but the organized lab project will not be moving forward.

One of the reasons that we developed Project Darkstar as an open source project was to allow the community to continue if the research objectives of the core team were changed. We will be maintaining the source repositories and the projectdarkstar.com site for as long as we can, but we are also investigating other homes for both the code and the supporting content.

As interesting as the technology development has been with Project Darkstar, I must say that I found the building of the community around that technology one of the most satisfying and interesting experiences of my professional life. I hope that the community will continue, and personally plan on at least observing and perhaps contributing (as an individual) to that continuation. Thank you all, and my very best wishes going forward. To the core team, I can only say that it was an honor and a privileged to work with you on this project and this technology.

간략히 요약하자면, “썬 에서는 더 이상 다크스타에 자원을 투입하지 않을 예정. 공시적인 개발은 더 없다. 웹 사이트와 소스 저장소는 가능한 유지 할 것이며, 코드와 지원 자료를 위한 공간을 찾는 중이다.”.

예전에 이 프로젝트 다크스타의 테크 데모를 봤지만 그 때 느낌으로도 “이거 망하겠네”였는데, 약 2년 반 정도 지난 지금, 프로젝트가 내려지는걸 보고있으니 기분이 좀 묘하긴하다.

내가 생각하는 실패 이유에 관해선 곧 글을 하나 더 써보기로 하겠다.

ps. 프로젝트 다크스타의 github 이름은 red-dwarf. Dark star 가 (겨우) red-dwarf가 되어버리다니… 참 의미심장하다?

리뷰: Coders at Work

Peter Seibel 의 coders at work 완독. 현업에 있는 / 있었던 유명 프로그래머 – 이쪽 업계에선 여러가지 의미로 슈퍼 스타 – 들의 인터뷰 15개를 엮어놓은 책이다.

인터뷰한 사람들의 면면을 살펴보면, 학계에 있던 사람부터 시작해서 (Knuth 교수라거나 haskell 의 Simon. Peyton-Jones, Guy Steel 등등), 업계에서 처음부터 지금까지 일해온 사람들(Live Journal을 만든 Fitzpatrick, 넷스케이프의 Zawanski, JSON의 Crockford, JavaScript의 Eich, Java Collections 의 저자 Bloch 등등) 혹은 양쪽 다에서 업적을 쌓은 사람들(AI 책의 저자이면서 구글의 리서치 디렉터인 Peter Norvig, UNIX와 C의 Ken Tompson 등등) 을 포함한다.

사실 이렇게 넓은 스펙트럼을 다루고 있어서인지, 프로그래밍에 관한 관점, 프로그래밍에 요구하는 관점, 어떤 언어가 필요한지, 자기 자신을 과학자/공학자/장인(craftsman)/예술가 중 무엇으로 보는지, 얼마나 수학을 해야하는지에 대한 생각이 각자 다르다. Literate Programming에 관해서는 대부분 괜찮지만 난 Knuth 수준으로 안해봤다가 대세였음…

일단 각 사람들이 다루는 분야가 프로그래밍 언어(C, Haskell, Smalltalk, Erlang, JavaScript, Fortress) 나 그에 밀접한 영역(Compiler, Interperter, EMACS(?), Java Collections)이거나, 아니면 현재 우리가 사용하는 시스템의 밑단(UNIX, ARPANET) 인 경우가 대부분이다. 어떤 의미로는 우리 시대의 – 적어도 컴퓨터 공학/전산학 분야에서는 – rocket science 인 듯…

프로그래머가 가져야하는 자질로,

  • 간단함, 명료함에 대한 추구
  • 자세한 것을 다룰 것
  • 추상화 해서 생각할 것
  • 수학적인 지식(분석적인 면 말고, 구성적(synthetic)인 면에서)
  • 새로운 분야에 대해 호기심을 가질 것

등을 말하고 있다.

다만 실제로 프로그래밍에 임하는 자세에는, “실제로 코드가 동작하고 이를 유지한다” 쪽에 치중하는 계열이 있고, “(API 적인) 명료한 인터페이스를 생각하고, 이를 잘 지지할 테스트를 만든다” 라는 사람들도 있었다. 그리고 정말 극단적으로는, 모든 코드를 종이 위에 작성하고 이걸 만들었더니 거의 버그가 없었다는 Knuth의 TeX도 있다. 허허허(…)

그리고 자기가 일하는 형태에 따라 자기가 과학자 혹은 공학자로 생각하는 경우가 많았고, 대부분 장인과 예술가 적인 면을 가지고 있다고 말했다. 많은 사람들이 C++ 의 거대해진 면에 대해서 비판적이었고, C/C++/Java 그리고 묵시적인 면에서는 python 등도 포함해서 포인터 기반의 연산을 가지고 있는 자체에 대해서 불만을 표시하기도 했다 – 그리고 이 인터뷰 내용을 다른 인터뷰 당하는 사람한테 말하고 반론이 나오기도 해서 꽤나 흥미로웠다(…).

인상적인 구절이 너무 많아서 – 예전에 Peter Norvig이 말한건 간단히 포스팅 했다 – 인용 + 인상 정리로 한 달은 우려먹을 수 있을 것 같지만 이건 이 책 읽을 이들의 즐거움을 위해서 패스하고, 내 맘에 든(…) 구절을 몇 개 정리해보겠다.

Zawanski: I was kind of freaked outwhen I realized that there are people graduating with CS degrees who’d never written C.

Joel Spolsky 가 말하는 거랑 비슷한 의미.

Fitzpatrick: The thing that annoys me about Java is that everyone has such a strong aversion to JNI stuff. Sometimes a library is in C++. The Python people – in the outside community and inside Google – don’t care. They’re like, “Oh, we’ll, SWIG-wrap-it.” They get on their way and they’re happy. Python gets support for something right away if it’s in C++ because they’re not religious about what the source language is.

Java people are like, “Must be pure Java. We cannot use JNI because then if the JVM crashes, we don’t know why.” The problem with that is you end up writing everythin twice, once for C++ and Python and all the other languages, and the once for Java. So if they could come up with a good embedding story or get over this fear of JNI, then I wouldn’t mind it.

Java를 쓰는 사람들이 “그냥 SWIG 래핑해서 쓰지”하는 Python 계열의 사람들과 달리, “JNI가 아니라서 크래시 나면 어딘지 알수 없잖아”라고 해서 라이브러리를 두번 작성한다고 불평. 다만 Java가 더 좋은 임베딩 방법을 찾거나, JNI 문제에 덜 신경쓰게 되면 좋겠단다… 이래서 내가 C++/Python 패러다임에 살고 있는지도.

Bloch: Even today, writing unit tests for concurrency utilities is an art form.

Mutex 버그로 고생했던 기억을 회상하면서, “병행성을 다루는 도구의 유닛 테스트를 작성하는건 아직도 예술의 영역이다”라고 말하고 있다 ㅠㅠ. 회사에서 내가짜는 유닛 테스트 중에 병행성 테스트는 없다(…). 그냥 부하 잔뜩 걸어서 테스트해보는 정도?-0-

Erlang 의 저자인 Joe Armstrong은 코드 재사용성의 문제가 OOP에 있다고 생각한다.

I think the lack of reusability comes in OO langueages, not in functional languages. Because the problem with OO languages is the’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

코드 재사용성을 (어느정도는) 강조하는 OOP지만, 실제적으론 묵시적으로 들고다니는 환경 때문에 너무 많은 의존성을 낳아 오히려 재사용이 안되고 함수형 언어에는 그런 문제가 없다는 것. 덤으로, 난 erlang을 함수형 언어로만 생각했는데, Armstrong 인터뷰에서 가장 많은 영향을 준 언어는 prolog 라고 말한다. PL 시간에 쌩고생 시킨 그 언어가 Orz

적절히 인용할 부분을 찾진 못하겠지만(…), SSA (컴파일러 이론의 static single assignment) 를 생각해내기도하고, 첫번째 튜링 어워드를 받은 여성인 Fran Allen은 “C의 성공 때문에 컴파일러가 최적화할 여지가 없거나 적은 언어들이 주류 언어가 되어버렸다”라고 비판했다. 즉, 좀 더 고수준의 언어를 가지고 만들어야 컴퓨터 공학이 발전할텐데, 시스템 프로그래밍 언어였던 C가 크나큰 성공을 거둬서 앞으로 갈 길이 너무 멀고, 발전이 너무 더디다라고 말한다.

이건 Python 도 저수준 언어의 기능 – 명시적인 메모리 공간에 대한 모델 – 이 있기에 겪을 수 있는 문제가 있는걸 생각하면, 약간은 수긍이 가는 듯도…

여기에 대해 ARPANET의 초기 구현을 작성한 Bernie Cossell은, 어셈블리어 프로그래밍을 하던 사람들에게 C의 표현력은 신선한 공기와 같아서 어쩔 수 없었고, 그 표현력과 저수준 지원 때문에 C는 다른 모든 언어 – 심지어 DoD가 우리와 계약하려면 Ada를 써라! 라고 했는데도 C가 더더욱 번성해버릴 정도로 – 보다 더 널리 쓰였다고 변호한다.

여튼 더 인용하고 싶은 문장은 매우 많지만, Bloch의 인터뷰를 인용해서, 내가 이 직업에 있는 이유를 설명해놓고 리뷰를 끝낸다.

What we’re doing is an aesthetic pursuit. It involves craftsmanship as well as mathematics and it involves people skills and prose skills – all of these things that we don’t necessarily thik of as engineering but without which I don’t hink you’ll ever be a really good engineer. So I thik it’s just something that we have to remind ourselves of. But I think it’s one of the most fun jobs on the planet. I think we’re really lucky to have grown up at the time that we did when these skills led to these jobs. I don’t know what we would have been doing a few generations back.

우리가 하고 있는 일은 미적인 추구다. 우리가 하는 일은 장인 정신 뿐만 아니라 수학과 사회적인 기술과, 글 쓰는 기술을 모두 필요로 한다. 이 모든게 공학에 꼭 필요한 거라고 생각되진 않지만, 이것 없이는 정말 뛰어난 공학자가 될 수 없다. 그래서 난 이것들이 우리가 상기해야할 무언가라고 생각한다. 그렇지만 난 이 일이 세상에서 가장 재밌는 일 중 하나라고 생각한다. 우리가 이 기술을 가지고 이 직업을 갖게만든 시대에 태어난걸 행운이라 생각한다. 만약 수 세대 전에 태어났다면 난 내가 뭘 하고 있을지 상상도 못하겠다.

컴퓨터 공학을 전공하고, “뭔가를 만들어보고 싶다”는 열망이 있다면 꼭 한 번 읽어보라고 권하고 싶은 책이다. 다만 다루는 내용으로 볼 때 이거 한국어판이 나올 수 있을까?-_-;

리뷰: Clean Code

twentyeleven

여러가지 의미에서 Kent Beck의 Implementation Patterns 과 비슷한 느낌의 책이다.

우리가 다루는 프로그래밍 추상화 단계 – 각 단위의 이름(변수나 함수, 클래스 등등…), 실행문(statement), 함수, 클래스, 시스템 레벨에서 어떻게 하면 “쉽게 읽고, 이해하고, 변경할 수 있는” 코드를 짤 수 있는지 설명한다. 그리고 comment나 클래스 설계 원칙에 대한 일반론들(open-closed principle, single responsibility principle…) 역시 다룬다. 사실 일종의 best-practice 북인 셈?

하지만 단순한 이런 류의 책에서 더 나아가서 – 개인적으론 이 부분이 Kent Beck의 Implementation Pattenrs 보다 훨씬 나은 점인 것 같다; 사실 TDD by examples 같은 느낌이기도 하다 – 실제 코드 (JUnit에서 따온 것도 있고, SerialiDate 클래스 같은 것도 있고 … ) 를 점진적으로 개선하는 실제 작업 내용을 한 단계씩 차근차근 밟아가면서 비교해주는 점이 좋았다. “나쁜 ???”에 해당하는 예를 적절히 보여준다는 것도 장점. 특히나 이것들을 “실제로 동작하는 프로그램”에서 가져온다는 점이 아주 좋음…

병행성(concurrency)에 대해서 다루는 부분도 읽을만 했다 – 물론 단점이 꽤 있다. 특히 처음 인용한,

“Objects are abstractions of processing. Threads are abstractions of schedule”

은 꽤나 맘에 듬.

곧 번역서가 나올 것이란 얘기도 있으니, 발간되고 나면 한 번 읽어보는 것도 괜찮겠다.

 

하지만 이 책에 단점이 없는 것은 아니다. 일단, 이건 개인적인거지만 Java 에 완전히 종속적인 부분이 나오며, 다른 언어에 대한 추가 고려는 없다(…). 그리고 첫 장에서 저자가 설명하듯이,

“모든 내용에 대해서 독자들이 동의할 거라곤 생각하지 않는다.”

에 해당하는게 꽤 보였다. 사실 그게 크게 작용한 것은 병행성 부분. 13 장과 부록에서 크게 다루고 있는데, 저자가 너무 지엽적인데 목매달고 있으며, library와 잘 알려진 concurrent data-structure/model을 쓰라고 하면서도, 정작 중요한(적어도 현재는) Java Executor Services에 대해선 너무 짧게 다룬다. Producer-consumer나 reader-writer 문제 같이 OS 시간에 다뤄서 충분할 내용들을 길게 다루고, 현재 OS나 platform 단에서 잘 정의해서 쓸 수있게 만든 executor service 나 Future construct에 해당하는 녀석들은 제대로 다뤄주지도 않는다.

실제로 여기서 설명하는 것들 – 공유 변수의 ++ 문제 – 같은 건 그냥 병행성 입문 교재에서 다루는 정도도 충분하다. 이 책의 다른 부분들 – 정도의 차이가 꽤 크긴 하지만 – 수준으로 다뤄졌어야 한다. 특히 병행성이 어떻게 구현될 수 있는지 – data parallel, task parallel … – 같은 부분은 거의 생략하면서, 실행 순서 문제나, lock 의 가벼운 정도(Java 5의 AtomicInteger vs. synchronized construct) 주제는 너무 길게 다루고, 큰 의미도 없다. 사실 더 중요한 캐시 친화적인 프로그래밍 같은건 싹 빠졌음 Orz.

실제로 synchronized 대신에 Atomic???  류를 쓰는 것이 좋긴 하다. 그렇지만 더 중요한 것은 lock 의 세밀함(coarse-grained vs. fine grained)이나, lock 자체를 피해갈 수 있는 전반적인 프레임웍 문제지, 지엽적인 주제에 집착하는 것은 그닥 좋지 않다. 이 부분의 저자가 컨설턴트인데 이러는 것도 좀 그렇긴하다(…).

차라리 이 부분은 적당히 건너뛰고, Art of concurrency나 Patterns for Parallel Programming, 혹은 Java Concurrency in Practice 같은 책을 보는게 이 항목에 대해선 좋은 선택인 듯 싶다.

총평: 일부 동의할 수 없는 내용이나, 미진한 내용(개인적으론 concurrency 부분의 두 챕터)이 있긴하지만, 전반적으로 괜찮은 책이니, 시간이 되면 한 번 읽어보시라.

리뷰: The Art Of Multiprocessor Programming

twentyeleven

특징: (공유메모리를 사용한) 멀티코어 프로그래밍 위주로 기술된 책이지만, 이론 쪽의 비중이 매우 충실하다 — 가능한 씨나리오의 나열과 고안된 알고리즘에 대한 수학적인 증명과 설명은 꽤 간결하다. 그리고 이런데 익숙하지 않더라도 책을 보는데 큰 무리는 없다.

처음 1/3은 이론, 그 다음 1/3은 이론과 구현이 섞인 상태로(compare-and-swap or compare-and-set 연산들을 이용한 것 포함), 마지막 1/3은 실제적인 것(고병렬 자료구조들은 정말 이 책의 백미다)들로 구성되어 있다. STM을 Haskell에 구현하기도 한 저자답게, 구현 코드의 질도 상당히 좋다.
하지만 가끔 코드에 대한 참조가 틀린다거나(지정한 번호 말고 다른 번호의 코드를 설명한다거나), 약간의 문제점을 내포한 코드도 있는 듯 하다.

장 점: 이론과 실제의 적절한 균형 — 보통 구현 얘기만 하거나, 학교 교재에 가까운 이론서 위주로 책이 나오니 — 이라는 점에서 앞으로의 대세일 수 밖에 없는 멀티코어 프로그래밍 쪽에 아주 유용한 책인 것 같다. Java의 concurrent 팩키지를 써서 독자가 순간순간 기억해야할 코드의 양을 적당히 유지해준다는 점도 만족스럽다.

단점: 코드가 Java 를 기준으로 작성되기 때문에, Java의 synchronized 블럭이나 Concurrent 팩키지의 내용들을 미리 알아야 한다. 그리고 이런 면들을 포함해서 책 자체가 멀티코어/멀티스레딩 프로그래밍 경험없이 읽기 쉬운 책은 아니다. 물론 부록의 내용으로 어느 정도 보충을 해주긴 하지만, 읽는데 경험이 필요하다는 것은 그런대로 단점.

즉, OS 정도는 수강하고 — 하다못해 시스템 프로그래밍 정도는 수강하고 — 읽을 것을 권하는 책. 더 이상 개별 코어의 속도는 거의 증가하지 않을 것이니 성능 문제에 대해 생각해보고 있다면 한 번 읽어도 좋은 것 같다. 특히 OS 시간 등에서 배우는 동기화 문제라거나, 병렬처리 수업 같은데서 배우는 성능 평가 개념들도 이론적으로 잘 정리해줘서 매우 유용한 책…이라고 생각 중.

지금 하고 있는 작업이 끝나면 다시 한 번 포스팅을 할듯(?)

Multi-core의 Concurrency를 위해선 멀티스레딩 뿐인가?

답은 아니다라고 생각한다 — 실제 현실도 그런 것 같고. 명확히 정리된 생각은 아니지만, 어제~오늘 생각했던 얘기를 풀어보겠다. 응용에 따라선 다른 방식으로 하드웨어(특히 CPU)의 concurrency를 끌어다 쓸 수 있을 것 같으니.[1]

멀티코어 / 멀티 CPU 머신이 시대의 흐름인 것은 거의 확실하다. 적어도 앞으로 수 년 정도 범위에서 CPU 기술의 방향은,

  • 메모리와의 통신 효율성 재고 — 현재 최대의 병목은 CPU – 메모리 통신이다
  • 캐쉬 용량 증대 — 앞에서 말한 효율성의 개선
  • CPU 코어 수 증가 — CPU 클럭을 올리는게 힘들어지지만 당분간은 트랜지스터 수는 늘릴 수 있으니 이 쪽일 것이다

일 거라고 생각한다. 이 중에 마지막 예측 때문에 허브 서터 같은 “대가” 들이 concurrency를 활용하기 위한 방안들을 설명하거나, 강조하고 있다. 그러나 한 프로세스 ((컴퓨터 공학의 OS 개론에서 말하는 process를 의미한다. OS에서 구분하여 자원을 관리해주고, 독립적인 메모리 영역을 갖는 단위를 의미한다.)) 의 성능 향상 범위에서 보면 이건 정확하다. 적어도 CPU 발전 방향이 코어 수 증가로 쏠려있는 상황에서는[2] 단일 프로그램의 1개 실행 속도가 올라가는데는 concurrency를 이용하지 않고는 한계에 직면한다. 뭐 “단일 프로그램”의 얘기다.

범위를 좀 더 확대해서 생각해보자.

1명의 사용자가 아니라 여러 명에게 서비스를 제공하는 “사업자” 측면을 생각해보자. 성능을 끌어올리기 위해 — 혹은 많은 사용자에게 서비스를 제공하기 위해 — 선택할 프로그래밍 모델은 세 가지 정도라고 생각된다.

  1. 멀티스레딩 or concurrent 응용을 만들어낸다. 게임 쪽에서 MMORPG 서버를 만들 때 이런 방식을 취한다.
  2. 같은 서비스를 제공하는 프로세스를 여럿 사용한다. 필요에 따라선 여러 개의 서버에 나눠 띄운다.
  3. 같은 서비스를 제공하는 여러 개의 프로세스[3] 를 만들고, 이들간의 통신 시스템을 만든다. 역시 필요에 따라선 여러 개의 서버에 나눠 띄운다.

아마 많은 경우에 프로그래밍 복잡도는 1 > 3 > 2가 아닐까. 반대로 scalability는 3 > 2 > 1 순서.

물론, 하나의 프로세스 실행을 가속할 방법은 1 밖에 없지만, 사업자 측면에서 보면 1~3 모두가 scalable한(확대 제공 가능한) 서비스를 만들어낼 수 있는 방법이다.

게임 서버 처럼 프로세스보다 작은 단위 — 예를 들어 게임 내의 NPC와 게이머의 상호작용, 게이머간의 상호작용, … — 에서 데이터 공유가 매우 많다면, 프로세스를 1개로 제한하는 수 밖에 없지만[4] , 그렇지 않은 상황에선 2/3 중에 적당한 것을 골라야 하지 않을까.

현존하는 초대형 웹 서비스들 — 웹 포탈이나 WordPress.com 같은 대형 호스팅 서비스들 — 은 3과 비슷한 구조를 가지고 있다. Load–balancer, 응용 서버 그리고 분산 DB로 이어지는 잘 정의된 분할을 가지고 있다. 물론 이런 대형 서비스들은 그것만으로 부족해서 구글의 분산 파일 시스템[5] 같은 도메인에 정말 잘 어울리는 응용을 개발해버리기도 하지만 :)

게임 서버의 경우에도 2, 3 과 같은 구현체들이 적지 않다. Sun의 Dark Star도 3과 유사한 구조를 가지고 있다 — 알려진 성능 평가는 “안습” 한 마디 빼고는 해줄 말이 없지만 -_-a.[6] 카트라이더나 많은 수의 MMOG — 사용자 간의 상호작용이 일정 수(30인 이하 수준)으로 유지되는 게임들 — 의 경우에는 3과 같은 구조를 만들어내기 쉽다. Front-end의 load-balancer와 뒷 단의 DB, 그리고 중간이 분산된 게임 서버들 구성을 하는 경우들이 있다.

이런 분산된 개별 게임 서버는 간단하게(…) 싱글 스레드/프로세스를 채용할 수 있게 된다. N모사 (내가 다니는 곳이 아닌 :p )에서 퇴사한 모군의 경우엔 싱글 스레드로 서버를 바꿨더니,

누구나 수정할 수 있게 되었어요!

라고 좋아하더라. 비슷하게 또 다른 개발자 한 분도, “굳이 멀티스레딩 쓸 이유있나요” 라는 뉘앙스의 얘기를.

사실 맞는 얘기다. 이런 구조에서 얻을 수 있는 병렬성이 있다 = 코어 수가 늘어갈 때도 분명히 이익이 있다. CPU 코어 수 만큼 게임 프로세스를 띄워버리면 되니까. 그럼 CPU를 낭비할 일도 없이(혹은 적게) 서버를 운영할 수 있게 된다.

그리고 위에서 후배 모군이 얘기한 것처럼 단일 스레드 프로그래밍은 쉽다. 굉장히 예측가능하고 인간의 뇌가 이해하기 쉽다. 다만 프로세스 간 통신이 힘들다는 근본적인 문제 때문에 만들어야하는 응용에 쓸 수 있냐없냐하는 문제가 있다. 오류가 발생해도 단순히 일부 게임들만 죽고(?) 끝나고, 개별 메시지를 처리할 때마다 오류처리를 아주 힘들게 할 이유가 없다 — 정 안되면 일부 게임을 포기하고 죽여버리면 되니까. 심지어 서버를 죽인다는 메모리 릭[7] 이 좀 있어도 일부 게임만 죽이면서(…) 프로세스를 다시 띄우는 방식으로 해결할 수 있다…[8]

그래서 MMORPG 서버처럼 무시무시하게 coupling된 시스템이 아닌 이상 잘 쪼갤 궁리부터 열심히 해야하지 않을까(…). 잘 쪼개고, 쉽게 (단일 스레드로) 가는게 개발자 건강에 유익하지 않을까 하고 잡 생각하는 밤이다.

ps. 완전히 여담이지만. 1의 구조로 가기엔 지금 우리가 가진게 너무 없다. STM이나 묵시적인 locking algorithm, 메시지 전송 같은 좀 더 편안하고, 안전하게 쓸 수 있는 primitive 혹은 개념들이 제공되기 시작했지만 멀티스레딩-concurrent programming이란 것은 저수준 시스템 프로그래밍에 가깝다;

OS에서 제공하지 않는 기능만으로 하기엔 한계가 있고, OS에서 제공하는걸 쓰자니 굉장히 저수준이 되어가고.[9]

  1. 엄밀한 의미로 말하면 concurrent-programming이 아닐 수도 있다. 모든 구성요소가 동시에 돌지 않아도 되는 내용위주로 글을 썼다. []
  2. 2003년에 2.4 Ghz CPU를 보편적으로 쓸 수 있었는데, 지금 사용하고 있는 intel Core2Duo CPU의 클럭이 겨우2.66Ghz다. 물론 캐쉬메모리의 증가, 명령어 파이프라인의 개선, 명령 실행 방식 변경(메모리 접근 재정렬), 명령의 병렬 수행 등등으로 “의미면에서의 실행속도”는 확실히 빨라지긴 했다. []
  3. 여러 프로세스가 한 묶음이 되게 []
  4. 혹은 가능하다면 통신량이 적을 곳 끼리 잘라내는 정도의 분할. 그러면 3에 조금 가까워진다. 상호작용이 많다는 문제 때문에 아무리 MMORPG 서버를 잘 만들어도, 한 서버(논리적인 의미에서)에서 처리하는 인원 수에는 한계가 있다. 가장 많은 인원을 처리한다는 Lineage II 서버도 이상적인 네트웍 상황에서 1개 서버에서 8천명 정도가 한계일 것이다. 물론 단일 서버 처리량으론 절대 작지 않다… []
  5. 검색 자체가 결과만 재빨리 나오면 되고, 굉장한 저장용량을 필요로 하지만 저장 공간 자체는 append-only 에 가깝게 쓴다는 특징들을 잘 이용해서 단순한 RAID로라면 하루 종일 디스크 교체만 해도 (전체 서버군이) 유지되기 힘든 문제를 해결했다. 논문이 꽤나 재밌지만 집에선 IEEE/ACM을 볼 수가 없군 -_- a []
  6. 서버간 병렬성으로 성능을 올리는 것은 둘째치고, 단일 서버 안에서는 당장 상용에서 쓰기 힘든 수준이라니 []
  7. 대부분의 경우 서버는 오래 떠 있을걸 가정하기 때문에, 아주 조금씩 새도 결국엔 물리 메모리를 다 채우고, 스왑핑을 하고, thrashing으로 들어가면서 CPU를 못 쓰게되고, 요청 속도를 처리 속도가 못 따라가게 되면서 서버는 사망. []
  8. 여담이지만 현재 회사 들어오기전에 저런 기능을 하는 코드를 진짜로 본 적이 있다… []
  9. 물론 boost::ASIO 팩키지나 ACE 프레임웍 처럼 각 OS의 저수준 기능을 잘 wrapping해서 제공하기도 하지만 그렇게 잘 되는 경우도 별로 흔하진 않은 것 같다. 당장 떠오르는게 저거랑 boost::thread 정도 뿐이니… Java도 epoll system call 같이 각 OS의 최적화된 I/O multiplexing을 쓰게된게 1.6 부터였던 것 같으니. []

SGS에 대한 실망, 감상

얼마 전에 Sun Microsystems의 CGO가 – 무슨 약자인지는 알아서 상상을 :p – SGS†라는 물건을 팔러왔다.

나름대로 기대도 하고 질문할 꺼리도 준비하고 보내준 자료도 분석하면서 이것저것 고민하고 질문 목록과 함께 미팅에 나갔다†. 그렇지만 결과는 요약하자면 포스팅 제목처럼 실망. 일단 실망한 것을 요약하자면,

  • Sun은 한국에 R&D 직이 없는 관계로 프로젝트를 진행하는 북미 엔지니어라도 오겠거니 했는데 온 것은 Sun CGO 한 명 달랑. 그리고 한국 Sun의 기술 영업 한명 + 영업 2명. 이거 뭔가효(…)
  • 일단 발표 자체는 발표 자료 수준. 물론 이 발표 자료의 수준도 웹 페이지의 그것을 크게 상회하지는 않는다.
  • 몇 가지 예상되는 질문, 특히 Java를 사용했을 때 언제나 따라붙은 꼬리표인 성능 문제에 대한 자료가 없다.

올 초에 이놈의 존재를 듣고 좀 파봤을 때는 별거없다 싶었는데, 그래도 볼륨이 좀 늘긴한듯하다. 그렇지만 준비한 몇 몇 질문들에 대해서는 명확한 답변이 없거나, “현재 프레임 웍에서는 불가능하다”라는 답변만을 얻었다. 그리고 좀 파고 들려했더니(…),

“온 사람 중에 엔지니어가 없다”

라면서 질문을 통짜로 회피해주시는 센스를.

싸우자!

미팅에 참가하다보니, 내 자신에 대해서도 실망한 점도 있었다. 특히 영어 Orz. 6년간 공대 실력을 했더니 읽기랑 듣기는 하겠는데 질문할 때는 뭐 이렇게 버벅대는지 Orz Orz Orz

ps. 우리 회사가 7번째 방문한 한국 회사라는데, 설마 엔지니어 한 명 없이 7개 이상의 회사를 돌았다는 소린가.

이글루의 박피디님이 본 관점.

*

† 이런 활동의 일환으로 얼마 전에 C++이후 세대의 언어로 게임 서버를 만드는게 어떨까에 관한 포스팅을 하고 몇몇 사람의 온/오프라인을 통한 생각을 얻어냈다.

‡ Sun Game Server. 혹은 프로젝트 다크스타.

¶ 댓글로 내가 질문구성하는데 크나큰 도움을 준 Rica, 선호군에겐 감사.