거창한 얘기를 하려는 것은 아님. 일반론을 좀 벗어난 단순한 사례를 하나 소개해보겠다.
지난 주말에 intel 에서 제공하는 threading building block[1] 의 해쉬 맵(tbb::concurrent_hash_map)과, MS VS 2005에서 제공하는 해쉬 맵(stdext::hash_map)의 성능을 비교하려고 간단한 프로그램을 짜기 시작했다. 성능평가를 위해 테스트할 순서를 다음과 같이 정했다.
개략적으로 내가 원했던 것은,
이런 식으로 두 가지 성능 차이를 낼 수 있는 원인을 분석하려고 한 것.
일단 내가 사용하는 컴퓨터가 그런데로 듀얼 코어니 거기서 테스트를 하려고 대충 이런 프로그램을 구상하고 작성했다.
근데 1에서 내가 직관적으로 생각한대로 동작하질 않는다. tbb::concurrent_hash_map 이 stdext::hash_map 보다 1.5배~3배 정도 빠르게 동작하는 것이다 -_-;; 생각했던 결론 — concurrent_hash_map이 더 복잡한 자료구조 + lock이 복잡하니 느릴 것이다 — 과는 완전히 모순되는 결과.
그렇지만 과학적 방법론을 사용한다면 폐기된 가설은 버리고 다른 원인을 찾아야지.
N을 바꿔가면서 테스트하니 결론이 나오더라. N 이 일정 크기 이하가되면 stdext::hash_map 의 성능이 상승하며, 일정 크기 이하에선 오히려 stdext::hash_map이 4배 이상 빠르다. 결국 원인은 이런 것.
결국은 성능 분석을 지배한 요인이 lock 의 오버헤드가 아니라 메모리 할당 속도였던 것.
성능 평가에 관한 내용은 경험 있는 엔지니어라도[2] 쉽게 말할 수가 없다. 복잡한 컴퓨터 시스템 만큼이나 요소는 많고, 결국엔 독립변수를 변화시켜가면서 돌려보고, 프로파일링해보고, — 그리고 이번 경우처럼 숨겨진 변인도 제거하고 — 적합한 패러미터를 찾아야 한다.
그러니 직관적으로(…) 성능을 평가하는 사람이 있다면 경계하자. 성능평가는 절대로 직관적이지 않다.
ps. 정작 저 둘의 성능 비교 이야기는 다음으로 미룬다 :p
No comments yet.
Jump to comments