출처 : http://gamedevforever.com/31

참고 1 : http://sunjinyang.wordpress.com/2009/04/29/tcmalloc-google-perftools/

참고 2 : http://ditto954.tistory.com/entry/TcMalloc-lib-%EC%A0%81%EC%9A%A9-%EC%8B%9C%EB%8F%84

참고 3 : http://dev.kthcorp.com/2011/06/01/mysql5-5-with-tcmalloc-benchmark/


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

 

 제가 이번에 다루어 보고자 하는 주제는 구글에서 만든 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 checker와 heap 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%의 성능 향상. 
같이 누려보시는 것은 어떨까요? 


'리눅스 서버에 대해서 > 리눅스 팁들' 카테고리의 다른 글

vi 기본설정  (0) 2013.01.10
putty 설정  (0) 2013.01.10
쉘 프로그래밍 강좌  (0) 2013.01.10
GNU Make 강좌  (0) 2013.01.07
이클립스에서 C++ 환경 만들기  (0) 2012.12.10

+ Recent posts