# TCmalloc (Thread-Caching memory allocation)
- https://code.google.com/p/gperftools/
- 구글이 만든 성능 도구에 포함되어 있는 힙 메모리 할당자로서 크롬 및 많은 프로젝트에 사용
- 기존의 malloc 으로 대표되는 할당자의 경우 멀티쓰레드의 최적화가 고려되지 않은 상황의 구현체이기 때문에, Thread가 난무하는 현실 세계에서는 많은 성능 저하가 있다고 함 (메모리 할당, 관리도 동시성을 고려해야 하므로..)
- 이쪽 계열 라이브러리 중에서는 가장 많이 알려져 있고, 기본 할당기에 비해 비약적인 성능 향상이 있다고 함.
- 그리고 적용 방법도 드라마틱 하게, 인상적임.
# 리눅스(Ubuntu, 14.10) 환경에서의 TCmalloc
- 패키지로 설치 하던가, 소스를 받아서 설치 하면 됨
sudo apt-get install libtcmalloc-minimal4
* 사용하는 방법 3가지
1. tc_malloc 및 tc_free 등의 함수를 사용하여 malloc 이나 C++의 기본 할당자를 직접 대체하는 방법
2. 라이브러리를 링크하여 C 및 C++ 기본 할당자는 대체하는 방법
TCmalloc는 라이브러리를 링크하는 것 만으로, C 및 C++의 기본 할당자를 tmalloc의 할당자로 대체 해줌.(Patch)
g++ -o mybin mybin.cpp -ltcmalloc_minimal
3. LD_PRELOAD를 이용하여 모듈을 먼저 로드(후킹)시킨 후, 기본 할당기를 대체하는 방식
허나 구글에서는 이 방법에 대해서는 tricky 한 방법이므로, 2번 방법을 사용 하도록 권고함
LD_PRELOAD=/usr/lib/libtcmalloc_minimal.so mybin
http://gperftools.googlecode.com/git/doc/tcmalloc.html
* 성능
- 극단적인 할당과 해제를 반복하는 멀티쓰레드 환경에서, 기본 할당자 보다 3배이상 빠른 결과를 보임
- 물론 일반적인 로직의 경우 메모리 할당, 해제에 관련해서 비중이 얼마나 많이 차이나느냐에 따라 다르겠지만, 메모리 할당에서의 성능 향상 뿐만 아니라, 지속적이 서비스로 인한 메모리 단편화를 감소시켜 바꾸는 것만으로 20% 정도의 성능 향상을 보인 다고 함.
# 윈도우 환경에서의 TCmalloc
- 소스 받아서 MSVC로 설치 하면 됨. 친절하게 MSVC 프로젝트 파일로 제공 됨
- 솔루션에 많은 프로젝트들이 보이는데, libtcmalloc_minimal 라고 되어 있는 프로젝트만 Release 로 빌드하면, 동적링크 모듈(DLL)로 빌드되고 정적으로 바꾸고 빌드해서 사용해도 무방한 것으로..
* 사용하는 방법 2가지
1. 위의 리눅스의 예와 같음. TCmalloc의 커스텀 할당자로 구현 하면 됨
2. 위도우 환경에서는 Patch 방식이 되지 않으므로, 라이브러리만 링크하는 것으로 끝나지는 않고 강제로 링크 심볼을 정의 함으로서 기본 할당자가 교체 되도록 설계 함 (이것도 멋짐!!)
// 소스에 아래와 같이 추가하여 라이브러리 참조 및 링크 심볼을 주입 함
#pragma comment (lib, "libtcmalloc_minimal")
#pragma comment (linker, "/include:__tcmalloc")
// 프로젝트 속성 환경에서 추가 할때는,
// 구성속성-링커-입력-추가종속성 에 명시하여 링크를 추가하고,
// 밑에 "강제 기호 참조"에 __tcmalloc 를 넣어주면 됨
* 성능
- 극단적인 환경에서는 30% 이상 효과가 있고, 일반적인 업무 로직에서는 그보다는 작겠지만 어느정도 성능 향상 효과가 있을 것으로 판단.
- 기본적으로 MSVC 환경에서의 메모리 할당자가 리눅스쪽의 것보다는 좋아 보임.
--
# JEMalloc
- Jason Evans가 만들었고, 페이스북이나 파이어폭스에서 사용 한다고 함
- 성능은 TCmalloc 보다 약간 좋다고는 (주장)하나, 개인적으로 테스트 할때는 TCmalloc 보다 약간 부족 했음.
- 구글링의 결과로는 보다 다이나믹한 멀티쓰레드 환경에서 최적화 되었다는데 반복적인 할당과 해제를 반복하는 예제에서는 그다지 많은 차이를 보이지 않음.
# 리눅스 환경에서의 JEMalloc
- http://www.canonware.com/jemalloc/
- TCmalloc 과 같이 소스 및 패키지 설치 지원
sudo apt-get install libjemalloc-dev
* 사용하는 방법
- 위의 TCmalloc과 같이 JEMalloc의 커스컴 할당기(je_malloc, je_free) 를 사용 하던가 LD_PRELOAD를 이용하여 사용하는 방법이 있음
- JEMalloc도 링크 만으로 기본 할당자를 교체 해주나, C언어의 기본 할당자 malloc 계열만 교체 해주고 C++의 것은 교체 해주지 않음. 그래서 C++에서 사용하려면(STL 등에서) 사용자 정의 할당자를 만들고 그 곳에 JEMalloc으로 할당 하는 방식으로 처리해야 함
- 리눅스의 경우 C, C++ 할당자를 모두 교체 지원 함
- 윈도우의 경우도 링크 참조만으로 기본 할당기를 교체해주지는 않고, header 파일을 이용해서 매크로로 C언어 기본 할당자를 교체 해주는 방식으로 처리 (#include <jemalloc/jemalloc.h>)
- Mingw (gcc 4.9.2)에서는 컴파일이 잘되나, MSVC(2013) 에서는 컴파일이 몇가지 문제를 일으킴
- Github에 Win32용 포팅 버전이 있으므로 그것을 받아서 빌드 하면 됨
# 기타
- nedmalloc : 윈도우즈 환경에 더 최적화 되었다는 nedmalloc 이런것도 있음. nedmalloc의 경우 자체 C언어 계열 커스텀 할당 함수와 C++의 allocator 를 대체할 클래스도 제공.
- tbbmalloc (Threading Building Blocks) : 인텔에서 만든 쓰레딩관련 라이브러리에 포함 되어 있는 힙 메모리 할당기
- 사이트에서 다운 받으면 OS별 바이너리가 들어 있음.
// linux
sudo apt-get install libtbb-dev
g++ -o mybin mybin.cpp -ltbbmalloc_proxy
// MSVC, tcmalloc 과 같은 방식
#pragma comment (lib, "tbbmalloc_proxy")
#pragma comment (linker, "/include:___TBB_malloc_proxy")
- Detours Express 3.0 : Detours is a library for intercepting arbitrary Win32 binary functions on x86 machines.
// 설치 후, 설치 디렉토리에서 nmake 로 빌드 후 사용
// dll 프리로드 후킹 (Windows)
withdll.exe /d:libtcmalloc_minimal.dll mybin
# 추가, 윈도우 테스트 결과 (참고용)
소스 : https://gist.github.com/cdecl/e7b414e8eff4a67c9396
* vc++ 기본 (msvc 2013)
[std::string alloc]
1585, 1656, 1600, 1707, 1628,
[malloc()]
1451, 1411, 1381, 1489, 1399,
* tcmalloc
[std::string alloc]
1156, 1150, 1195, 1045, 1184,
[malloc()]
560, 586, 564, 571, 564,
* tbbmalloc (Threading Building Blocks)
[std::string alloc]
1003, 973, 963, 998, 1000,
[malloc()]
811, 782, 780, 813, 807,
# 추가, 리눅스 테스트 결과 (참고용)
- 소스 : malloc 반복횟수 및 옵티마이저 안되게 끔 위의 소스 수정
* 기본 (g++ 4.9.1)
[std::string alloc]
3931, 3904, 3945, 3902, 4044,
[malloc()]
1434, 1422, 1447, 1457, 1411,
* tcmalloc
[std::string alloc]
1112, 1125, 1161, 1099, 1091,
[malloc()]
355, 333, 328, 351, 334,
* jemalloc
[std::string alloc]
1451, 1442, 1396, 1427, 1411,
[malloc()]
438, 483, 432, 462, 457,
* tbbmalloc
[std::string alloc]
1856, 1843, 1820, 1868, 1842,
[malloc()]
750, 701, 765, 764, 752,
참고 :
one malloc to rule them all
http://blog.reverberate.org/2009/02/one-malloc-to-rule-them-all.html
Scalable memory allocation using jemalloc
Benchmarks of the Lockless Memory Allocator
http://locklessinc.com/benchmarks_allocator.shtml
C++ memory allocation mechanism performance comparison (tcmalloc vs. jemalloc)
'Dev > C++' 카테고리의 다른 글
cdecl/asb 개발 중.. (0) | 2015.04.01 |
---|---|
cdecl/asb - Http benchmarking and load test tool for windows, posix (0) | 2015.03.18 |
Catch (A modern, C++-native, header-only, framework for unit-tests, TDD and BDD) (0) | 2015.02.26 |
C++ REST SDK (casablanca) 간단 샘플 (0) | 2015.02.17 |
[C++11] Variadic template (0) | 2014.11.02 |