프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 라오그람

안녕하세요.  라오그람이란 필명을 사용하는 김효진 입니다. 저는 서버 개발을 하고있구요, 원래는 게임 서버 개발자이지만 현재는 게임쪽이 아닌 잠시 다른 서버 분야를 개발하고 있습니다.  없는 실력에 네임드 분들 사이에서 글을 쓴다는 것이 영광스럽기 그지 없네요ㅠㅠ 앞으로 더욱 열심히 공부해서 좋은 글을 쓰도록 하겠습니다.
 

 

 제가 이번에 다루어 보고자 하는 주제는 구글에서 만든 TCMalloc입니다



 보통 멀티 스레드 환경의 서버를 만들다 보면 메모리 풀을 사용하게 됩니다. 메모리 풀의 이점은 다음과 같습니다.


첫째, 빠른 메모리 할당.

둘째, 메모리 단편화 감소.

하나의 커다란 메모리 풀을 사용하면 단순하게 malloc을 호출해서 메모리를 할당하는 것 보다 속도가 빠릅니다. 메모리 풀에 따라 다르겠지만 일반적으로 볼 때 처음 프로그램이 실행될 때 필요한 메모리를 통째로 잡아놓고 메모리가 필요한 경우에는 잡아놓은 메모리 안에서 잘라서 주기 때문이죠. 하지만 멀티 스레드 환경에서는 메모리 풀도 속도가 저하됩니다. 왜냐하면 여러 스레드에서 하나의 메모리 풀에 접근을 하게 되면 lock에 대한 cost가 발생합니다. 동시에 접근하는 스레드가 많을 수록 lock을 기다리는 시간이 많아지고 그러다보면 메모리를 얻기 위하여 기다리는 스레드들은 일을 할 수 없게 됩니다.

 lock cost로 인한 속도 저하는 또 다른 방법으로 해결 할 수 있습니다.

thread별로 따로 메모리 풀을 두고 관리하고 
다른 thread에서 접근 해야 하는 메모리는 전역 메모리 풀을 두어 관리하고… 
뭐 이런 식으로 메모리 풀을 설계하면 되죠. 


하.지.만 

귀찮잖아요? 


그래서 친절하신 구글에서 우리들을 위하여 TCmalloc(Thread Caching malloc)이란 이름으로 메모리 할당하는 라이브러리를 내어 놓았습니다.

 

 이름도 거창하게 Thread Caching을 달고 나오신 TCmalloc은 메모리를 Thread Local Cache와 Central Heap으로 나누어서 관리합니다. Thread Local Cache는 32K이하의 작은 오브젝트 들을 담당하며 메모리가 부족할 시에는 Central Heap에서 메모리를 얻어와서 할당합니다. 그리고 32K가 넘어가는 큰 오브젝트들은 Central Heap에다 4K의 페이지 단위로 나누어서 메모리 맵을 이용하여 할당합니다. 사실 단순한 Central Heap은 일반적으로 사용하는 메모리 풀과 다를 바 없습니다. 하지만 Thread Local Cache가 있음으로 해서 메모리 할당시 불필요한 동기화가 줄어들게 되고 그에 따른 lock cost가 꽤 많이 감소되어 성능이 향상됩니다.

 특히 리눅스 환경에서는 pthread_mutex_t가 거지같이(?) 느리기 때문에 개인적으로는 꽤 많은 향상을 얻을 수 있었습니다. 자체적으로 만든 memory pool과 비교해보고 나서 '나는 무엇을 하고 있었나' 라는 심한 좌절감을 느꼈었죠Orz...


 TCmalloc의 사용법은 정말 간단합니다. 다운로드를 받고 설치를 한 후 라이브러리를 링크 해주면 끝납니다. 헤더파일 Include이런 것 전혀 필요 없습니다. 단지 TCmalloc 라이브러리를 링크해주는 것 만으로 malloc이 TCmalloc으로 바뀌는 마법 같은 효과를 얻을 수 있습니다.

 

구글에서는 이렇게 말하고 있습니다. 

- TCmalloc을 사용하려면 Linker flag에 "-ltcmalloc"을 넣으면 된다. 

- 따로 컴파일 할 필요 없이 $ LD_PRELOAD="/usr/lib/libtcmalloc.so"를 해주는 것으로도 효과를 볼 수 있다. 하지만 이것은 편법이기 때문에 추천하지는 않는다.'


단순하게 -ltcmalloc을 넣는 것 만으로 메모리 할당에서 20%이상의 성능향상을 얻을 수 있다니 참 쉽죠?
(윈도우에서는 
Project Dependencies에 추가해 주시면 됩니다) 

더불어 TCmalloc을 사용하면 구글에서 제공하는 heap checkerheap profiler까지 덤으로 사용할 수 있게 됩니다. 


< 스레드 수와 메모리 용량에 따른 TCMalloc과 PTMalloc이 CPU초당 처리할 수 있는 횟수 비교>
Mops : Millions operations per second 
 



출처 : Google TCmalloc Document에서 발췌
* 자세한 내용은 링크를 따라가시면 보실 수 있습니다.


위의 표를 보면 Single Thread에서는 크게 효과를 보지 못합니다. 하지만 Thread의 수가 늘어날 수록, 메모리 단위가 작을 수록 TCmalloc이 효율이 더 뛰어난 것을 보실 수 있습니다.

위의 내용이 길고 두서없어서 읽기 귀찮으신 분들을 위하여 간단하게 요약을 하자면...

1. Google Performance Tools Home에서 Google Performance Tools를 다운 받는다.
2. INSTALL파일을 읽어보고 자신의 환경에 맞게 설치한다. 
3. Library를 링크시키고 사용한다.
4. 성능 향상이 일어난다!!!!



 아직 게임 서버에는 적용을 해 볼 수 없었지만 현재 하고 있는 프로젝트에서는 memory allocator를 TCmalloc으로 대체하고 난 이후 평균적으로 20%정도의 성능 향상이 일어났고 메모리 할당에 대한 속도 저하 걱정을 많이 덜 수 있었습니다.  요즘은 유저들의 PC가 좋아짐에 따라 클라이언트들도 꽤 많이 멀티스레드를 지향하고 있다고 들었습니다.

몇 분의 투자로 20%의 성능 향상. 
같이 누려보시는 것은 어떨까요? 

댓글을 달아 주세요

  1. Favicon of http://rhea.pe.kr/ Rhea君 2012.01.05 09:47  댓글주소  수정/삭제  댓글쓰기

    당장...은 무리고 저녁때 설치해서 써보겠습니다.
    좋은 라이브러리 소개 감사합니다.

  2. Favicon of https://hgcoder.tistory.com hgcoder 2012.01.05 10:15 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다 ^^
    코드상에서는 아무것도 하지않고 링크만으로 끝나는건가요?
    ㄷㄷㄷㄷ

  3. sgpro 2012.01.05 10:26  댓글주소  수정/삭제  댓글쓰기

    고맙습니다. ^^

  4. Favicon of http://bluekms21.blog.me 크로스 2012.01.05 13:29  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다. 구글은 저런 라이브러리도 배포하는군요.. 흠흠!
    그런데 읽다가 몇가지 궁금한점이 생겼는데요

    일반 메모리 풀 - 락에 의한 대기시간 발생
    스레드마다 별도의 메모리풀 & 공용 메모리 풀 - 귀찮다
    라고 쓰여있는데... 그렇다면

    1) TCMalloc - 락에 의한 대기시간도 없으며, 여러 스레드가 매모리에 접근할 수 있다 인가요??
    (TCMalloc에 대한 설명(어떤 원리로 기존것보다 좋은가)이 없어서 좀 아쉽네요;;)

    2) 비교대상이 되는 PTMalloc도 정확히 어떤 의미로 쓰였는지 알고싶습니다.

    • Favicon of https://gamedevforever.com 라오그람 2012.01.06 13:10 신고  댓글주소  수정/삭제

      1) TCMalloc - 락에 의한 대기시간도 없으며, 여러 스레드가 매모리에 접근할 수 있다 인가요??

      - 설명이 많이 부족했네요 ㅠㅠ 죄송합니다;; TCMalloc도 Lock cost가 생길 수 있습니다. 하지만 Thread별로 메모리 할당이 각각 되기 때문에 커다란 메모리 풀을 하나 두고 사용하는 것 보다는 Lock cost가 많이 줄어들게 됩니다.
      예를 들자면..
      큰 메모리 풀을 하나 잡는 경우 :
      - PC를 하나 주고 계정을 하나를 주면서 10명에게 같이 사용하라고 하는 것과 비슷하다면...

      TCMalloc을 사용할 경우:
      - 10명에게 개인용 PC를 한 대 씩 지급하고 자유롭게 사용하라는 것과 비유할 수 있을 것 같네요.(Threading Cache)

      - 하지만 공용 PC도 한 대 지급하고 있어서 커다란 작업은 공용 PC에서 개개인의 계정을 할당 받아서 그 영역 내부에서 사용하는 것이구요.(Central Heap)

      물론 A라는 Thread에서 B라는 Thread의 data를 참조하려면 Lock이 필요 할 것입니다. 하지만, 메모리 할당을 하는 부분에서는 Lock에서 자유로울 수 있겠죠~ 글에도 썼듯이 충분히 구현도 가능할 것입니다. 하지만 저는 있는 라이브러리는 쓰는게 좋다 주의라서 ^^;;

      2) 비교대상이 되는 PTMalloc도 정확히 어떤 의미로 쓰였는지 알고싶습니다.

      - PTMalloc 은 리눅스 기반에서 일반적으로 사용하는 malloc입니다. ptmalloc2로 알고있는데요... 리눅스를 설치하시면 malloc을 부를 때 호출되는 놈으로 보시면 됩니다. 윈도우 같은 경우는 제가 윈도우를 손에서 놓은지 1년이 넘다보니;; 잘 모르겠고요... MAC같은 경우는 TCMalloc과 비슷한 원리인 Jemalloc이 기본으로 탑재되어있다고 알고있습니다. (Jemalloc은 facebook에서 사용해서 이슈가 되었었죠~)

      제가 알고있는 부분이 이정도까지라 만족스러운 답변이 되었는지 모르겠습니다^^;;

  5. 게으른아해 2012.01.05 17:50  댓글주소  수정/삭제  댓글쓰기

    "하지만 귀찮자아요?"에서 빵 터졌습니다"ㅎㅎ
    좋은 내용 감사합니다

  6. 꼬꼬마칭구 2012.01.09 20:30  댓글주소  수정/삭제  댓글쓰기

    저기... 관련부서가 아니시라서 모를수도 있으시겠지만

    던파 버그좀 어떻게 해줘요 으어엉엉ㅠㅠㅠ

    남법사 버그는 무궁무진하고 소울끌잡 이건뭐 ㅠㅠ 스탠딩 버그는 또 왜생긴거야 ㄴ마우민읜ㅁ


    rlasoaen@naver.com ㅠ

  7. Favicon of https://blueasa.tistory.com blueasa 2012.01.29 02:08 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다.
    짬내서 바로 한번 적용해 봐야겠습니다. :)