곱셈의 덫 – 편지 봉투 뒷면을 써야할 시점

오후에 ticket 하나를 꺼내서 슥슥슥 구현을 하고나서, 테스트가 통과하나 테스트를 돌리는데 이게 왠 걸, 통과는 하는데 원래 1.x 초면 (늦어도 3초?) 끝나던 것들이 1분씩 걸리고 있는 것.

뭔가 버그를 집어넣었구나 하고 이전 revision과 현재 작업 사본을 diff 한 다음에[1] 뭐가 다른가 확인.

대충 10여분 코드 리뷰를 하는데 — diff에 대해서만 하니까 — 잘못된 곳을 못찾겠더라. 디버거를 들이대고 동작을 따라가는데 이상한 점을 찾을 수 없었다.

생각없이 작업관리자를 띄워서 CPU를 어디서 먹을까 하고 보고있는데 CPU 사용량은 거의 0%고, 메모리 사용량이 (시스템 전체에 대해) 2GiB 를 초과 — 물론 가상 메모리 크기가 그런 것이고, 실제로 commit 된 메모리 용량은 그보다 작은(대략 700MiB)라서 thrashing까지 본 것은 아니지만 여튼 CPU는 별로 안 써도 성능은 Orz

그 상태에서 나눈 대화.

[rein] …님의 말:
테스트셋이 메모리 2기가 먹고있으면 릭이겠지(…)
▩▦ㅅ/지름신 actually.님의 말:
릭이 아닐수도
[rein] …님의 말:

▩▦ㅅ/지름신 actually.님의 말:
이런 경우도 있을수 있긴 하더라고
시작 -> 메모리 할당 -> 메모리할당->메모리할당 -> 끝날때쯤 왕창 deallocate
머 확률은 별로 많지 않지만 그런 경우도 있긴 있더라능(머엉)

…ㅅ(…)의 말대로 버그는 아니더라.[2]

문제(…)를 확인하고 난 후의 대화.

[rein] …님의 말:
원인 찾았음

객체당 메모리를 4메가쯤 쓰는데
내가 걔내를 400개 좀 넘게 할당하더라


▩▦ㅅ/지름신 actually.님의 말:
ㅋㅋㅋ
그런거 먼가 오래 돌리면 돌릴수록 사용량이 linear하게 증가하잖 ;-;ㅎ
시작할때 왕창 400개 숑 한건가?
[rein] …님의 말:

근데 그게
테스트 케이스 시작할 때 몽땅 만들고
끝날 때 해제하는데
테스트 케이스가 한 20개 되나

▩▦ㅅ/지름신 actually.님의 말:
ㅋㅋㅋ
[rein] …님의 말:
Orz
▩▦ㅅ/지름신 actually.님의 말:
너도 걸렸구나 그케이스(…)
나도 전회사 있을때 그 케이스에 걸렸는데 윗사람들이 릭이라고 우겨대서
졸 개로웠

(내가 테스트 안만들었는데!!;-; )

메모리 할당량을 추적해보니 각각의 테스트 셋에 대해서 개별적으로 1.6GiB 을 넘는 정도의 용량이 할당되고, 제거되더라. 그래서 내가 할당하는 객체에 대해 계산을 해봤다.

  • 전체를 총괄하는 A 객체는 총 16개 할당된다
  • A가 할당하는 B 객체가 각각 26개가 할당
  • B 객체마다 작업 데이터가 약 4MiB 씩 존재

…곱해보면 약 1.7 GiB. 덕분에 성능저하를 체험하게 되는 것. Diff에서 내가 추가한 내용도 잘 분석해보면 저 4MiB 데이터가 이전에는 4KiB 수준이었거든. 그렇지만 데이터가 필요한 수준으로 커지면서, 그리고 객체 할당의 계층을 따라 이루어진 곱셈과 합쳐지자 결과는 -_-;;

실제 서비스에나 올라갈 데이터량을 — 실제론 이거보다 커지겠지만 — 가지고 테스트하고 있던 것이라 A, B 두 객체의 할당 수를 테스트 셋에나 쓸 수준으로 깎고 나서는 해결.

여러 단계를 거친 곱셈은 무섭다. 단순한 직관에서 생각한 범위보다 훨씬 큰 무언가를 다루게 되니…

Programming Pearls[3] 에서 말한 것 처럼 봉투 뒷면에 하는 계산[4] 은 수시로 해봐야 된다. 내가 이상한데로 엇나가는지 판단하기 위해서라도.

  1. 소스 코드 관리 도구에서 이전에 사용하던 버젼과 현재 작업하고 있는 것(현재 작업 사본;Working copy)과의 차이를 쉽게 볼 수 있는 기능을 제공한다. 이건 현존하는 대부분의 툴들이 그러할듯… []
  2. 그리고 ㅅ이 말한 경우에 해당 — 테스트 시작할 때 왕창 할당하고, 끝날 때 다 푸는데, 중간에 오래 걸리니까 최대 할당량을 계속 보게되는 것 []
  3. 생각하는 프로그래밍이란 제목의 한국어판 서적도 있다 []
  4. back-of-the-envelope calculation – 편지 봉투 뒷장정도에 간단히 할 수 있는 계산으로, 시스템 전체에 필요한 요구사항을 간략히 분석하는 것. 그렇지만 많은 경우에 이런 간단한 계산으로도 상당히 필요한 범위를 좁게 잡아낼 수가 있다. []

Author: rein

나는 ...

Leave a Reply