마지막 그림자, 동기화 비용

902025년 09월 16일5

CSS 페인트 워크릿과의 성공적인 통합은 WebGPU의 영향력을 웹 플랫폼의 가장 깊숙한 곳까지 확장시켰다. 이제 웹의 모든 시각적 요소는 잠재적으로 GPU의 힘을 빌릴 수 있게 되었다. 하지만 이 놀라운 유연성은, Dawn 팀이 예상치 못했던 새로운 종류의 성능 병목을 드러냈다.

이번에도 신호는 크롬의 자동화된 성능 테스트 시스템, 텔레메트리에서 왔다.
시스템은 수백 개의 WebGPU 페인트 워크릿이 적용된 복잡한 웹 페이지를 스크롤하는 시나리오를 테스트하고 있었다.

보고서의 내용은 뜻밖이었다.
“스크롤 애니메이션의 프레임 속도가 간헐적으로 저하되는 현상 발견. CPU 프로파일링 결과, 특이점 없음. GPU 프로파일링 결과, 셰이더 실행 시간 양호. 병목의 원인이 불분명함.”

원인 불명의 성능 저하.
엔지니어에게 이보다 더 끔찍한 말은 없었다.

드미트리는 이 문제를 해결하기 위해, Dawn의 TBR 백엔드를 설계했던 레나를 포함한 최고의 성능 분석 전문가들로 작은 TF 팀을 꾸렸다. 그들은 이제 브라우저의 모든 동작을 나노초 단위로 추적하는, 가장 깊은 수준의 디버깅에 돌입했다.

그들은 몇 날 며칠을 시스템의 내부 동작과 씨름했다.
그리고 마침내, 레나가 그 ‘보이지 않는 병목’의 실체를 찾아냈다.
그녀는 팀 회의에서, GPU 타임라인을 시각화한 복잡한 그래프를 화면에 띄웠다.

“여러분, 문제는 여기에 있습니다.”
그녀가 그래프의 특정 구간을 가리켰다.
“이 구간은, 렌더링 엔진(Blink)이 컴포지터에게 ‘이제 화면을 그려달라’고 명령을 내리는 부분입니다. 그리고 컴포지터는 수백 개의 페인트 워크릿이 생성한 텍스처들을 모아 최종 화면을 합성하죠.”

그녀는 그래프의 작은 틈새들을 지적했다.
“바로 이 틈새들. 이것이 병목의 원인입니다. 이것은 ‘동기화 비용(Synchronization Cost)’입니다.”

그녀가 설명하는 문제는 이러했다.
수백 개의 페인트 워크릿은 각자 독립적으로 자신만의 텍스처를 렌더링한다. 컴포지터는 이 모든 텍스처가 ‘완전히 준비될 때까지’ 기다려야만 최종 합성을 시작할 수 있었다.
이 ‘기다리는’ 과정에서, GPU는 아무 일도 하지 않고 시간을 허비하고 있었다.

마치 수백 명의 요리사가 각자 자신의 요리를 만들고, 모든 요리가 완성되어야만 서빙을 시작할 수 있는 레스토랑과 같았다. 한 명의 요리사라도 늦어지면, 모든 손님은 하염없이 기다려야 했다.

“우리는 지금까지 개별 셰이더의 실행 시간, 개별 submit 호출의 효율성에만 집중해왔습니다. 하지만 이제 시스템 전체의 관점에서 보니, 작업과 작업 사이를 연결하는 이 ‘기다림’ 자체가 가장 큰 비용이 되고 있었던 겁니다.”

이것은 API 레벨에서 해결할 수 있는 문제가 아니었다. 이것은 브라우저의 렌더링 파이프라인 전체의 동작 방식을 바꿔야 하는, 거대한 수술이었다.

드미트리는 이 문제를 해결하기 위해, 컴포지터 팀의 마리아와 다시 한번 머리를 맞댔다.
그들은 수많은 논의 끝에, ‘종속성 그래프(Dependency Graph)’라는 개념을 도입하기로 했다.

드미트리가 설명했다.
“이제 렌더링 엔진은 컴포지터에게 단순히 ‘이 텍스처들을 합성해줘’라고 말하는 대신, 텍스처들 사이의 관계 정보를 함께 넘겨주는 겁니다.”

예를 들어, ‘텍스처 C는 텍스처 A와 텍스처 B가 모두 완성된 후에야 비로소 렌더링될 수 있다’는 식의 의존성 정보를 그래프로 표현하여 전달하는 것이다.

“그러면 컴포지터는 더 이상 맹목적으로 기다릴 필요가 없습니다. 이 종속성 그래프를 보고, GPU 스케줄러와 협력하여 작업의 순서를 최적으로 재배치할 수 있게 됩니다. A와 B를 렌더링하는 동안, GPU의 남는 자원을 활용하여 C와는 상관없는 D 텍스처를 미리 렌더링하는 식으로요. GPU의 유휴 시간을 최소화하는 겁니다.”

이것은 브라우저가 GPU를 사용하는 방식을, 단순한 명령어의 나열에서, 지능적인 작업 스케줄링 시스템으로 한 단계 진화시키는 발상이었다.

이 거대한 아키텍처 변경 작업은 크롬의 여러 팀이 참여하는 대규모 프로젝트로 발전했다.
Dawn 팀은 WebGPU가 생성하는 작업에 대한 종속성 정보를 노출하는 API를 추가했다.
Blink 렌더링 팀은 이 정보를 수집하여 종속성 그래프를 구축하는 로직을 만들었다.
그리고 컴포지터 팀은 이 그래프를 해석하여 GPU 작업을 최적으로 스케줄링하는 지능형 컴포지터를 개발했다.

몇 달간의 대수술 끝에, 새로운 시스템이 적용된 빌드가 나왔다.
그들은 다시 한번, 수백 개의 페인트 워크릿이 포함된 페이지의 스크롤 테스트를 실행했다.

결과는 놀라웠다.
이전에는 주기적으로 발생하던 프레임 저하 현상이 완전히 사라졌다. 스크롤은 마치 기름칠이라도 한 듯 부드러웠다. GPU 타임라인 그래프에서 보이던 수많은 작은 틈새, 즉 ‘기다리는 시간’들이 모두 사라지고, GPU는 쉴 틈 없이 효율적으로 움직이고 있었다.

드미트리는 이 결과를 보며, 플랫폼 엔지니어링의 본질에 대해 다시 한번 생각했다.
때로는 가장 큰 성능 향상이, 가장 빠른 셰이더나 가장 효율적인 알고리즘에서 오는 것이 아니었다.
그것은 시스템의 각 부분들이 서로를 기다리며 낭비하는, 그 ‘보이지 않는 비용’을 찾아내고 제거하는 데서 온다.

그의 역할은 이제, 시스템이라는 거대한 기계의 톱니바퀴들이, 서로의 발목을 잡는 대신, 완벽한 리듬에 맞춰 함께 돌아갈 수 있도록, 그 사이의 마지막 남은 마찰까지 제거하는, 세심한 정비공의 역할로 확장되고 있었다.