빌드 끝나고 한참 멈춰있던 그 단계, 기억나세요?
Xcode나 LLVM 기반 툴체인으로 큰 프로젝트를 빌드해본 분이라면, 컴파일이 다 끝났는데도 마지막에 뭔가가 한참 돌아가는 경험을 해보셨을 거예요. 그 정체불명의 단계 중 하나가 바로 dsymutil이에요. 이번에 이 dsymutil이 내부 엔진을 완전히 갈아엎고 병렬 처리 방식으로 바뀐다는 소식이 나왔는데, 디버깅 경험에 꽤 큰 영향을 줄 수 있어서 짚어볼게요.
dsymutil이 대체 뭘 하는 친구냐면
먼저 배경부터요. 우리가 코드를 컴파일하면, 변수 이름이나 줄 번호 같은 "디버그 정보"가 DWARF라는 형식으로 만들어져요. 이게 있어야 나중에 크래시가 났을 때 "몇 번째 줄에서 터졌어"라고 알 수 있거든요.
그런데 애플 플랫폼에선 이 디버그 정보가 각각의 .o 오브젝트 파일에 흩어져 있어요. 이걸 한데 모아서 .dSYM이라는 별도 묶음 파일로 만들어주는 게 바로 dsymutil의 역할이에요. 흩어진 퍼즐 조각을 모아서 하나의 완성된 디버그 지도를 만든다고 생각하면 돼요. 앱이 크래시 났을 때 의미 없는 메모리 주소 덩어리를 사람이 읽을 수 있는 함수 이름과 줄 번호로 바꿔주는(이걸 "심볼리케이션"이라고 해요) 핵심 재료가 이 dSYM 파일이고요.
뭐가 문제였고, 어떻게 바꿨나
기존 dsymutil의 가장 큰 약점은 DWARF를 합치는 링킹 과정이 사실상 단일 스레드였다는 거예요. 요즘 노트북도 코어가 8개, 16개씩 되는데, 정작 이 무거운 작업은 코어 하나만 붙들고 끙끙대고 있었던 거죠. 그래서 디버그 심볼이 많은 대형 프로젝트일수록 이 단계가 병목이 됐어요.
새로 도입되는 병렬 DWARF 링커는 이 작업을 여러 컴파일 단위로 쪼개서 여러 스레드가 동시에 처리하도록 바꿨어요. 핵심 아이디어는 이래요. 각 오브젝트 파일의 디버그 정보를 독립적으로 분석할 수 있는 부분과, 마지막에 서로 연결해야 하는 부분(예를 들어 여러 파일이 공유하는 타입 정보)으로 나눈 다음, 독립적인 부분은 병렬로 쫙 처리하고 합치는 단계만 조율하는 방식이에요.
여기서 까다로운 게 타입 중복 제거예요. 똑같은 구조체나 클래스 정의가 여러 파일에 중복으로 들어 있는데, 이걸 하나로 합쳐야 dSYM이 비대해지지 않거든요. 그런데 여러 스레드가 동시에 "이 타입 내가 처리할게"라고 달려들면 충돌이 나잖아요. 이 부분의 동기화를 잘 설계하는 게 병렬 링커 구현의 핵심 난이도였다고 해요. 결과적으로 멀티코어를 제대로 활용하면서 출력 결과는 기존과 동일하게 유지하는 걸 목표로 만들어졌어요.
업계 맥락
사실 "링커를 병렬화한다"는 흐름은 dsymutil만의 이야기가 아니에요. 일반 링커 쪽에서도 이미 mold나 LLVM의 lld 같은 차세대 링커들이 "링킹은 더 이상 병목이면 안 된다"며 멀티스레드 병렬화로 엄청난 속도 개선을 보여줬거든요. 컴파일러는 파일별로 병렬화가 쉬운데, 모든 걸 하나로 합치는 링크 단계는 본질적으로 직렬적이라 그동안 최적화의 사각지대였어요. dsymutil의 이번 변화도 같은 맥락에서, "빌드 파이프라인의 마지막 직렬 구간들을 하나씩 병렬로 풀어나가는" 큰 흐름의 일부라고 볼 수 있어요.
한국 개발자에게 주는 시사점
iOS·macOS 앱을 만드는 분이라면 이건 그냥 공짜로 빨라지는 개선이에요. 툴체인이 업데이트되면 별다른 설정 없이 dSYM 생성 시간이 줄어들 가능성이 크거든요. 특히 CI 서버에서 릴리즈 빌드마다 dSYM을 만들어 크래시 리포팅 툴(Firebase Crashlytics, Sentry 같은)에 올리는 팀이라면 빌드 시간 단축 효과를 체감할 수 있을 거예요.
더 넓게 보면, "직렬로 돌던 작업을 병렬로 바꿀 때 어떤 부분을 독립시키고 어떤 부분만 동기화할지 나누는" 사고방식은 우리 일상 코드에도 그대로 적용돼요. 데이터 처리 파이프라인이든 배치 작업이든, 이 사례처럼 "독립적인 부분은 최대한 병렬로, 합치는 지점만 최소한으로 조율"하는 패턴은 두고두고 써먹을 수 있어요.
마무리
눈에 잘 안 띄는 빌드 도구 하나도 멀티코어 시대에 맞게 끊임없이 진화하고 있다는 게 인상적이에요. 느려서 당연하다고 여겼던 단계도, 사실은 아직 최적화의 여지가 남아있던 거죠.
여러분의 프로젝트에서 "느린 게 당연하다"고 그냥 받아들이고 있는 단계는 없나요? 혹시 그것도 병렬화의 사각지대일지 한번 들여다보면 어떨까요?
🔗 출처: Hacker News
TTJ 코딩클래스 정규반
월급 외 수입,
코딩으로 만들 수 있습니다
17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공