프로그래밍/의문
비쥬얼 스튜디오에 tcmalloc 간단 적용
제페
2016. 7. 22. 15:15
반응형
- Google 퍼포먼스 툴 다운로드
https://code.google.com/p/gperftools/
- Zip 파일 압축 해제 후 gperftools.sln 실행
- libtcmalloc_minimal 프로젝트 빌드
- 만들어진 dll과 lib를 복사한다.
- 프로젝트를 만들고, lib 파일을 포함하고 링크 심볼을 정의해준다.
#pragma comment(lib, "libtcmalloc_minimal")
#pragma comment(linker, "/include:__tcmalloc")
이렇게 하면 기존의 메모리 할당(malloc이나 new 같은)이 내부적으로 tcmalloc을 사용하도록 대체를 한다는데.. 적용이 매우 간편하다는 점이 매력적이다.
++ 2018-04-18
#pragma comment를 이용하지 않고 아닌 비주얼 스튜디오에서 사용하는 방법은 다음과 같다.
프로젝트에서 속성 - 구성 속성 - 링커 - 입력으로 가 추가 종속성에 libtcmalloc_minimal.lib를 추가하고, 강제 기호 참조에 __tcmalloc을 써주면 된다.
로컬에서 어느정도 차이나는지 간단하게 보고 싶었다.
다음 코드의 윈도우 기본 메모리 할당자를 이용한 속도와 tcmalloc를 이용한 속도는 각각 다음과 같았다.
(tcmalloc과 같은 메모리 풀 라이브러리가 최대한의 효과를 발휘하려면 메모리의 할당/해제가 많아야 한다.)
#include <iostream>
#include <chrono>
#include <vector>
#include <numeric>
void DoTest(int count)
{
auto start = std::chrono::steady_clock::now();
std::vector<long long> vec;
std::vector<char*> chunks;
for (int cnt = 0; cnt != count; ++cnt)
{
for (int len = 1; len != 8; ++len)
{
long long v = 0;
char* p = new char[len];
for (int idx = 0; idx != len; ++idx)
{
p[idx] = (p[idx] | 0xFF);
}
for (int idx = 0; idx != len; ++idx)
{
v = p[idx];
}
vec.push_back(v);
chunks.push_back(p);
}
for (auto p : chunks)
{
delete[] p;
}
chunks.clear();
chunks.shrink_to_fit();
}
auto end = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "len: " << vec.size() << std::endl;
std::cout << "sum: " << std::accumulate(vec.begin(), vec.end(), 0ll) << std::endl;
std::cout << elapsed.count() << "ms" << std::endl;
}
int main()
{
DoTest(10000000);
int t;
std::cin >> t;
return 0;
}
기본 할당자 이용: 15414ms
tcmalloc 이용: 3814ms
이렇게 보니 큰 차이가 있어 보이지만, 실제 개발하는 어플리케이션에 적용해서 데이터 로드 속도에서의 차이를 확인하니 10%의 성능 향상도 없었다. (이 데이터 로드에는 i/o가 껴있다보니 더더욱 그랬다.)
tcmalloc은 visual studio 디버그 모드에서 실행 시 크래쉬를 일으킨다. : http://zepeh.tistory.com/434
반응형