Quantum 시대 – 어떻게 Firefox는 다시 빨라졌는가? 그리고 더 빨라질 것인가?

Firefox가 다시 달려가기 시작했습니다.

Tweet from Sara Soueidan about Firefox Nightly being fast

지난 7개월 동안, 우리는 신속하게 Firefox  주요 엔진의 대부분을 대체했습니다. 즉, Rust와 Servo의 일부를 추가했습니다. 또한, 성능 문제에 대해 코드 베이스를 샅샅이 뒤져서 브라우저 성능에 대한 파격적인 변화를 주었습니다.

그동안 Project Quantum을 통해 베타 테스트를 거쳐, 오늘 Firefox Quantum을 출시하였습니다.

orthographic drawing of jet engine

이것은 끝이 아닌 시작입니다만, 파이어 폭스가 어떻게 다시 빠른 속도와 성능을 가질 수 있었는지에 대한 기술적인 부분을 살펴 보겠습니다.

덩어리 방식(Coarse-grained) 병렬 처리 방식으로 기초 다지기

빠른 속도를 얻기 위해, 지난 10 년 동안 하드웨어의 진화된 방식을 활용해야 했습니다.

이는 처음이 아닙니다. Chrome은 처음 출시되었을 때 Firefox보다 빠르고 반응이 뛰어났습니다. 그 이유 중 하나는 Chrome 엔지니어가 당시 컴퓨터 프로세서에 대해 좀 더 확인하고, 새로운 하드웨어를 더 잘 사용하기 시작했기 때문입니다.

Chrome looking to the future of coarse-grained parallelism

당시 새로운 스타일의 CPU가 인기를 얻고 있었습니다. 이러한 CPU에는 여러 코어가 있어 서로 독립적으로 작업을 수행 할 수 있으며, 동시에 병렬로 수행 할 수 있습니다.

그러나, 이것은 까다로울 수 있습니다. 병렬 처리를 사용 하면  디버그하기 어려운 미묘한 버그를 만들 수 있습니다. 예를 들어, 두 개의 코어가 동일한 수의 메모리에 1을 더해야 하는 경우 특별한 주의를 기울이지 않으면 다른 코어를 덮어 쓰게 됩니다.

diagram showing data race between two cores

이런 종류의 버그를 피하는 아주 직접적인 방법은 작업 중인 두 가지가 메모리를 공유하지 않는 것입니다. 즉, 많은 작업을 할 필요가 없는 매우 큰 작업으로 나누면 됩니다. 이것이 덩어리 방식으로 메모리를 관리하는 병렬 처리입니다.

브라우저에서 이러한 덩어리를 찾는 것이 매우 쉽습니다. 각 탭을 별도의 작업 덩어리로 만듭니다. 또한, 웹 페이지 주변에는 브라우저 크롬이 있으며 별도로 처리 할 수 ​​있습니다.

이렇게 하면 페이지가 서로를 차단하지 않고 동시에 자신의 속도로 작업 할 수 있습니다. 백그라운드 탭에서 장기 실행 스크립트가 있는 경우, 그 탭에서 작업을 차단하지 않습니다.

이것은 Chrome 브라우저 엔지니어가 발견한 새로운 방식입니다. 우리도 이를 살펴 보았습니다만, 거기에 도착하기 위한 좀 더 세심한 길을 걸어왔습니다. 파이어폭스는 크롬과 달리 기존 코드 기반이 있었기 때문에 다중 코어를 활용하기 위해 코드 기반을 분할하는 방법을 새로 계획해야 했습니다.

Firefox looking to coarse-parallelism future

시간이 좀 걸렸지만, 이제 최종적으로 도착했습니다. Electrolysis 프로젝트를 통해 마침내 모든 사용자를 위한 다중 프로세서 처리 방식을 만들었습니다. 그리고, Quantum은 몇몇 다른 프로젝트와 함께 덩어리 방식의 병렬 처리를 사용하고 있습니다.

timeline for coarse grained parallelism, with Electrolysis and Quantum Compositor before initial Quantum release and Quantum DOM after

Electrolysis

Electrolysis는 Project Quantum의 토대를 마련했습니다. Chrome에서 소개 한 것과 유사한 일종의 다중 프로세스 아키텍처를 도입했습니다. 이러한 큰 변화가 있었기 때문에, 이를 2016년에 시작된 소수의 사용자 그룹과 테스트를 거쳐, 2017 년 중반에 Firefox 베타 사용자에게 배포했습니다.

Quantum Compositor

GPU process

Quantum Compositor는 프로세스로 잘 관리하며, Firefox를 보다 안정적으로 만들었습니다. 별도의 프로세스가 있으면, 그래픽 드라이버가 충돌하여 Firefox가 모두 중단되지 않습니다. 이렇게 별도의 프로세스를 사용하여, Firefox가 더 빠르게 반응합니다.

Quantum DOM

콘텐츠 창을 코어 사이에서 분리하고, 각 콘텐츠 창마다 별도의 주 스레드가 있는 경우에도 주 스레드가 수행해야 하는 많은 작업이 여전히 있습니다. 이들 중 일부는 다른 것보다 중요합니다. 예를 들어, 키 누르기에 응답하는 것이 가비지 콜렉션을 실행하는 것보다 중요합니다. Quantum DOM은 이러한 작업의 우선 순위를 정하는 방법을 제공합니다. 이로 인해 Firefox가 더 빠르게 반응합니다. 대부분 기능 탑재가 완료되었으나, 선제 계획 (pre-emptive scheduling)이라고 불리는 작업을 계속 진행할 계획입니다.

세분화 된(fine-grained) 병렬 방식 지향

미래를 내다 볼 때,  덩어리 방식 병렬 처리보다 더 멀리 나아갈 필요가 있습니다.

Firefox looking towards the future of fine-grained parallelism

덩어리 방식 병렬 처리는 하드웨어를 더 잘 사용하지만… 이를 최대한 활용하지는 못합니다. 서로 다른 코어에서 이러한 웹 페이지를 분리하면 일부는 수행 할 작업이 없습니다. 그러면 그 코어는 유휴 상태가 됩니다. 동시에 새 코어에서 실행되는 새 페이지는 CPU가 단일 코어 인 경우처럼 오래 걸립니다.

Splitting content windows across different cores

새로운 페이지가 로딩 될 때 해당 코어를 모두 사용하여 처리 할 수 ​​있다면 좋을 것입니다. 그러면 그 일을 더 빨리 끝낼 수 있습니다.

덩어리 방식 병렬 처리로 인해 하나의 코어에서 다른 코어로 작업을 분리 할 수는 없습니다. 작업 사이에는 경계가 없습니다.

세분화 된 병렬 처리를 사용하면 큰 작업을 작은 단위로 분해하여 다른 코어로 보낼 수 있습니다. 예를 들어, Pinterest 웹 사이트와 같은 것이 있으면 다른 고정 된 항목을 분리하여 처리 할 대상을 다른 코어로 보낼 수 있습니다.

Splitting work across cores fine-grained

이것은 덩어리 방식 병렬 처리 된 것처럼 대기 시간을 줄이는 데 도움이 되지 않지만, 순수한 처리 속도로 도움이 됩니다. 작업이 모든 코어에서 분할 되므로 페이지가 더 빨리 로딩됩니다. 더 많은 코어를 추가하면 더 많은 코어를 추가 할수록 페이지 로딩 속도가 계속 높아집니다.

이것이 미래라는 것을 알지만, 거기까지 가는 방법이 완전히 명확하지 않았습니다. 세분화 된 병렬 처리를 빠르게 수행하기 때문에 일반적으로 코어간에 메모리를 공유해야 합니다. 그러나 그것은 제가 전에 이야기했던 데이터 경주 문제가 생깁니다.

우리는 브라우저가 이러한 변화를 해야 한다는 점을 알고 있었기 때문에 연구에 투자하기 시작했습니다. 이러한 데이터 경주 문제에서 벗어난 언어인 Rust를 만들었습니다. 그런 다음  세분화 된 병렬 처리를 최대한 활용 한 브라우저 엔진 인 Servo를 만들었습니다. 이를 통해 이 방법이 효과가 있으며 빠른 속도로 진행되는 동안 실제로 버그가 줄어들 수 있음을 입증했습니다.

timeline of fine grained parallelism, with Quantum CSS before initial Qunatum release, and Quantum Render and possibly more after

Quantum CSS (aka Stylo)

Cores that have finished their work stealing from the core with more work

Stylo를 사용하면 CSS 스타일 계산 작업이 모든 CPU 코어에서 완전히 병렬 처리됩니다. Stylo는 코어간에 작업을 효율적으로 분리하여 작업을 유지합니다. 이것으로 선형 속도 향상을 얻을 수 있습니다. 여러분이 가지고있는 많은 코어에 의해 CSS 스타일 계산을하는 데 걸리는 시간을 나눕니다.

Quantum Render (featuring WebRender)

Diagram of the 4 different threads, with a RenderBackend thread between the main thread and compositor thread. The RenderBackend thread translates the display list into batched draw calls

고도로 병렬화 된 하드웨어의 또 다른 부분은 GPU입니다. 수백 또는 수천 개의 코어를 가지고 있습니다. 하지만 이 코어가 최대한 바쁠 수 있도록 많은 계획을 세워야 합니다. 이것이 WebRender가하는 일입니다.

WebRender는 2018년에 최신 GPU를 활용할 예정입니다. 그 동안 우리는 또 다른 각도에서 이 문제를 살펴 보았습니다. 고급 레이어 프로젝트는 배치 렌더링을 지원하도록 Firefox의 기존 레이어 시스템을 수정합니다. Firefox의 현재 GPU 사용 패턴을 최적화하여 즉각적인 성과를 얻었습니다.

 

???

우리는 렌더링 파이프 라인의 다른 부분들도 이런 종류의 미세한 병렬 처리로부터 이익을 얻을 수 있다고 생각합니다. 앞으로 몇 달 동안이 기술을 사용할 수 있는 곳을 더 자세히 살펴볼 것입니다.

더 빠르게 그리고 다시 느려지지 않기 위한 노력

우리가 알아야 할 이러한 주요 아키텍처 변경 외에도, 많은 성능 버그가 있을 수 있는 것을 찾기 위해 코드를 다시 보았습니다.

그래서, 이것을 고치기 위해 Quantum의 또 다른 부분을 만들었습니다. 기본적으로 이러한 문제를 발견하고 팀을 동원하여 문제를 해결하는 브라우저 성능 타격 기능입니다.

 

timeline of Quantum Flow, with an upward sloping arc

Quantum Flow

Quantum Flow은 특정 하위 시스템의 전반적인 성능에 초점을 맞추기보다는 소셜 미디어 피드 로딩과 같이 매우 특정한 사용 사례를 설정하고 Firefox에서 응답 속도가 느린 이유를 파악했습니다.

Quantum Flow 덕분에 많은 성과를 거둘 수 있었습니다. 또한 이러한 유형의 문제를 쉽게 찾고 추적 할 수 있는 도구와 프로세스를 개발했습니다.

우리는 이러한 과정을 한 번에 하나의 주요 사용 케이스를 식별하고, 초점을 맞추어 성공적으로 성능 개선을 수행하여 워크 플로우의 일반적인 부분으로 전환했습니다. 이를 위해 개발 및 테스트 도구를 개선하여 엔지니어에게 더 많은 권한을 부여할 수 있었습니다.

그러나, 이 접근법에는 한 가지 문제점이 있습니다. 유스 케이스 하나를 최적화하면 다른 유스 케이스를 최적화 할 수 없습니다. 이를 방지하기 위해 성능 테스트를 실행하는 CI 자동화 개선, 사용자 경험을 추적하는 원격 측정, 버그 내부 회귀 관리 등 새로운 추적 기능이 추가되었습니다. 이를 통해 Firefox Quantum의 지속적인 개선이 기대됩니다.

 

이제 시작입니다!

지난 한 해 동안 우리는 Firefox를 빠르게 만들기 위해 열심히 노력했습니다. 그러나 이것은 시작에 불과합니다. 2018년에는 지속적으로 새로운 성능 향상을 제공 할 것입니다. 우리는여러분과 이를 공유하기를 기대합니다!

Firefox Quantum 다운로드 하거나 Developer Edition을 통해 새로운 기능 개선을 확인해 주시기 바랍니다.

이 글은 Lin ClarkEntering the Quantum Era—How Firefox got fast again and where it’s going to get faster의 한국어 번역입니다.

작성자: Channy Yun

Channy Yun가 작성한 문서들…


2 댓글

  1. 오현석

    세부 기반(fine-grained) 병령 방식 지향 -> 병령이 아니라 병렬이겠죠? ^^

    세부 기반은 좀 어색한 것 같습니다. “세분화한” 정도는 어떨까요?

    11월 22nd, 2017 at 2:29 오후
  2. Seol

    일단 아래 내용과 동일하게 “세분화 된”으로 변경하였습니다.
    “병령”은 “병렬”로 변경하였습니다.
    의견 주셔서 감사합니다.

    12월 22nd, 2017 at 10:26 오후

댓글 쓰기