프로그래밍/c++
boost::pool_allocator는 생각만큼 빠르지 않다?
제페
2016. 1. 23. 08:09
반응형
간단한 코드를 보자!
하나는 boost::pool_allocator로 부터 shared_ptr 할당을, 하나는 기본 new 연산자로 shared_ptr 할당을 한 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #include <future> #include <chrono> #include <iostream> #include <boost/pool/pool_alloc.hpp> #include <boost/chrono/stopwatches/stopwatch.hpp> using namespace std; struct obj { int a; int b; int c; }; using pool_allocator_type = boost::pool_allocator<obj>; size_t test_loop_count = 100000; size_t test_func_count = 1000; pool_allocator_type alloc; void make_shared_test() { std::shared_ptr<obj> pobj; for (size_t i = 0; i != test_loop_count; ++i) { pobj = std::make_shared<obj>(); } } void allocate_shared_test() { std::shared_ptr<obj> pobj; for (size_t i = 0; i != test_loop_count; ++i) { pobj = std::allocate_shared<obj>(alloc); } } int main() { auto shared_test_result = std::async([]() { boost::chrono::stopwatch<> watch; watch.restart(); for (size_t i = 0; i != test_func_count; ++i) { make_shared_test(); } auto count = watch.elapsed().count(); cout << "shared_test_result: " << count << endl; }); auto allocate_shared_result = std::async([]() { boost::chrono::stopwatch<> watch; watch.restart(); for (size_t i = 0; i != test_func_count; ++i) { allocate_shared_test(); } auto count = watch.elapsed().count(); cout << "allocate_shared_result: " << count << endl; }); shared_test_result.wait(); allocate_shared_result.wait(); std::system("pause"); return 0; } | cs |
당연히 pool에서 할당한게 더 빠르지 않아? 라고 생각할 수도 있지만..
결과
차이가 더럽게 큰 부분에서 pool_allocator가 얼마나 느린지는 충분히 파악 가능하다.
pool을 사용하면서 이렇게 느리다니? 이유가 뭘까
바로 여러 스레드에서 pool_allocator에 접근할 때를 대비해 내부적으로 동기화를 하기 때문이었다.
동기화에 발생되는 비용 때문에 저런 큰 차이가 벌어진다는 것.
동기화 때문에 벌어진 차이이므로, 이 문제를 해결하기 위해선 사용하는 mutex를 null_mutex로 바꾸면 된다.
1 | using pool_allocator_type = boost::pool_allocator<obj, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex>; |
자, null_mutex로 바꿨으니 다시 퍼포먼스를 확인해보자.
결과
pool을 사용해 allocate_shared를 하는 것이 약 2배 가까이 빨라진 것을 확인할 수 있다.
반응형