카테고리 없음

#CPU, GPU, 메모리, 그리고 멀티프로세스 구조

ASI23 2023. 4. 1. 18:21
https://developer.chrome.com/blog/inside-browser-part1/
이 글은 2018년에 작성된 마리코 코사카님의 글을 번역한 것입니다. 

이 4파트의 블로그 시리즈에서, 우리는 높은 수준의 아키텍처에서 렌더링 파이프라인의 구체적인 사항들에 이르기까지 크롬 브라우저 내부가 어떻게 작동하는지에 대해 알아볼것이다. 

만약 당신이 브라우저가 당신이 작성한 코드를 웹사이트로 어떻게 바꾸어 작동시키는지나, 퍼포먼스 향상을 위해 특정 기술이 필요한 이유에 대해 궁금해한 적이 있다면 이 시리즈는 당신을 위한 것이다.

 

이 시리즈의 첫번째 파트로써, 우리는 코어 컴퓨팅 용어들과 크롬의 다중 프로세스 구조에 대해 알아볼 것이다.

#컴퓨터의 코어는 CPU 와 GPU이다.

브라우저가 굴러가는 환경에 대해 이해하기 위해서는, 우리는 몇개의 컴퓨터 파츠들이 어떻게 굴러가는지에 대해 이해해야 한다.

 

#CPU

첫번째는 CPU(Central Processing Unit)이다. CPU는 컴퓨터의 뇌 라고 할 수 있다. 이 그림에서 사무 노동자로 그려지는 CPU 코어는 그들에게 들어오는 서로 다른 과제들을 하나씩 다룰 수 있다. CPU는 수학부터 미술까지, 그들이 고객들의 요청에 어떻게 대응해야할지 안다면 모든걸 다룰 수 있다. 과거에 대부분의 CPU들은 하나의 칩으로 구성되어 있었다. 코어는 같은 칩에 있는 다른 CPU와 같다. 

현재 CPU에서, 우리가 사용하는 대부분의 CPU들은 두개 이상의 코어가 장착되어 있기에 우리의 핸드폰이나 노트북에 더 높은 작업 역량을 부여한다.

4개의 CPU 코어가 직장인처럼 들어오는 요청들을 처리하고 있다.

#GPU

GPU(Graphics Processing Unit)은 컴퓨터의 또 하나의 부품이다. CPU와 다르게, GPU는 동시에 여러개의 코어를 사용하는 단순 작업들에 특화되어 있다. 이름에서 보여주듯이 GPU는 그래픽작업을 위해 개발되어있다. 이것이 GPU를 사용하는 것이 빠른 렌더링이나 부드러운 상호작용에 연관된 이유이다. 

최근 몇년간 GPU 가속 컴퓨팅을 통해, GPU만으로 더 많은 양의 컴퓨터 작업들을 처리하는 것들이 가능해졌다. 

많은 GPU코어들이 렌치를 들고 들어오는 주문을 처리하고 있다.

우리가 컴퓨터나 핸드폰에서 응용 프로그램을 구동시키면, CPU와 GPU가 응용 프로그램의 전원을 킨다. 대부분의 상황에서 응용 프로그램들은 운영체제에서 제공되는 메커니즘들을 통해 CPU와 GPU에서 작동한다.

 

 

컴퓨터의 3층 구조. 기계장치가 가장 아래에 위치하고, 운영체제가 가운데, 응용 프로그램이 상단에 위치하고 있다.

 

#프로세스에서의 프로그램 실행과 스레드

도우미인 스레드를 품고 있는 프로세스와 물고기로 묘사한 스레드

브라우저 구조에 대해 알기 전에 파악해야할 개념은 프로세스와 스레드이다.

사전적 의미에서 프로세스란 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램을 말한다. 즉 동적인 개념에서는 실행된 프로그램을 의미한다. 

사전적 의미에서 스레드란 프로세스 내에서 실행되는 여러 흐름의 단위이다. 

 

우리가 응용 프로그램을 실행할때, 프로세스가 생성된다.

프로그램은 작동을 돕기 위해 선택적으로 스레드를 생성한다(스레드를 생성할수도 안할수도 있다). 이 흐름에서 스레드는 프로세스의 도우미라고 할 수 있다. 프로세스가 요청받은 작업을 수행하기 위해 스레드의 도움이 필요하다 싶으면, 프로세스가 할당받은 자원을 스레드들끼리 공유하게 해서 작업을 수행한다.

 

운영체제는 프로세스가 함께 작동할 '슬래브'를 주고, 모든 응용프로그램 상태는 개인 메모리 상태에 저장된다. 

(슬래브란 건축에서 쓰이는 용어로, 일정한 두께를 가지는 평판 형태의 부재로, 가해지는 하중을 분산시키는 역할을 한다.)

프로세스는 운영체제에서 받은 슬래브를 통해 스레드들에 작업들을 분배한다라고 생각하면 편할 듯 하다.

응용프로그램을 닫으면 모든 프로세스는 사라지고 운영체제는 메모리를 비워낸다. 

메모리 공간을 사용하는 프로세스와 응용 프로그램 데이터 저장에 대한 다이어그램

 

프로세스는 다른 작업을 수행하기 위해 운영체제에게 다른 프로세스를 실행하도록 요청할 수 있다. 그럴 경우, 메모리의 다른 부분들이 새로운 프로세스에 할당된다. 만약 두개의 프로세스가 서로 소통을 필요로 할 경우, IPC(Inter Process Communication)라는 내부 프로세스 커뮤니케이션을 통해 수행할 수 있다. 많은 응용 프로그램들은 만약 한 프로세스가 응답하지 않을 경우, 문제없는 다른 프로세스들에 영향이 가지 않게 문제가 발생한 프로세스만 종료하고 작업을 지속할 수 있도록 설계되었다.

 

IPC를 통해 분리된 프로세스들끼리 소통하는 다이어그램

 

#브라우저 구조

그렇다면 웹 브라우저는 프로세스와 스레드들을 사용하여 어떻게 만들어졌을까? 브라우저는 수많은 스레드들과 하나의 프로세스로 만들어졌을 수도 있고, 수많은 프로세스들과 IPC를 사용하는 몇개의 스레드로 이루어져 있을 수도 있다.

프로세스와 스레드 다이어그램에서 서로다른 브라우저 구조

여기서 짚고 넘어갈 중요한 사실은 이런 서로 다른 구조들이 구현 세부 정보라는 것이다. 웹 브라우저를 구축하는 방법에 대한 표준 사양은 존재하지 않는다. 어떤 브라우저의 접근 방식은 다른 브라우저와 완벽하게 다를 수 있다.

 

이 블로그 시리즈에서, 우리는 아래의 다이어그램을 통해 그려진 크롬의 현재 구조에 대해 알아볼 것이다.

 

이 그림의 맨 위에는 응용 프로그램의 다른 부분을 관리하는 다른 프로세스와 조정되는 브라우저 프로세스가 있다. 렌더 프로세스 과정에서, 여러개의 프로세스가 만들어져서 각 탭에 할당된다. 최근까지 크롬은 가능하면 각 탭에 프로세스를 제공했지만 이제는 iframe을 포함하여 각 사이트에 자체 프로세스를 제공하려한다.

Chrome의 다중 프로세스 구조 다이어그램.

#각 프로세스가 무엇을 컨트롤할까?

다음 테이블은 크롬의 각 프로세스가 컨트롤하는것들에 대해 보여준다.

프로세스가 컨트롤 하는 요소들
브라우저 주소 바, 북마크, 앞뒤 화살표 버튼등을 포함하는 응용프로그램의 크롬 파트를 컨트롤한다.
렌더러 웹사이트가 보여지는 탭 내의 모든것을 컨트롤한다.
플러그인 플래시와 같이 웹사이트에서 사용되는 플러그인들을 컨트롤한다.
GPU 다른 프로세스들에서 GPU 작업들을 분리해서 다룬다. GPU가 여러개의 응용프로그램들의 요청들을 처리하고 같은 환경에서 제시하기 때문에 GPU 작업들은 분리되어 다루어진다.

 

이 외에도 확장 프로세스나 유틸리티 프로세스등의 다른 프로세스들이 더 존재한다. 만약 얼마나 많은 프로세스들이 지금 우리가 쓰는 크롬에서 굴러가는지 궁금하다면, 브라우저 우측 상단 메뉴 아이콘의 옵션을 눌러서 도구 더보기를 선택하고, 작업 관리자를 고르면 볼 수 있다.

윈도우 환경에서 현재 진행되고 있는 프

서로 다른 브라우저 UI를 가리키는 서로 다른 프로세스

로세스들이 CPU/메모리 사용량과 함께 보여진다.

 

#크롬의 다중 프로세스 구조의 이점

이전 텍스트에서 크롬이 다중 렌더 프로세스를 사용한다고 언급했었다.

대부분 간단한 상황에서, 각 탭은 고유한 렌더러 프로세스를 가진다. 우리가 3개의 탭이 열려있고, 각 탭은 독립적인 렌더러 프로세스를 통해 작동한다고 가정해보자. 만약 하나의 탭이 응답하지 않는다면, 그 탭 하나만 닫으면 다른 탭들은 그대로 작동하는 것을 볼 수 있다. 만약 모든 탭들이 하나의 렌더러 프로세스로만 작동한다면, 하나의 탭이라도 응답하지 않을 경우 모든 탭이 작동하지 않게된다. 

 

브라우저의 일을 여러개의 프로세스로 분할하는것의 또 다른 장점은 보안과 샌드박싱이다. 운영체제가 프로세스 권한을 제한하는 방법을 제공하기 때문에, 브라우저는 특정 기능의 특정 프로세스만 타겟으로 샌드박싱 하는 것이 가능하다. 예를 들어 크롬 브라우저는 렌더러 프로세스처럼 임의의 사용자 입력을 처리하는 프로세스에 대한 임의 파일 액세스를 제한한다.

각 탭에서 작동하는 여러개의 프로세스들을 보여주는 다이어그램

프로세스들은 자체 메모리 공간을 가지고 있기 때문에 종종 공통 인프라(Chrome의 JavaScript 엔진인 V8과 같은)의 복사본을 포함한다. 이는 동일한 프로세스 내부의 스레드일 경우 공유할 수 없기 때문에 메모리 사용량이 더 높아진다는 것을 의미한다. 메모리를 절약하기 위해서는 크롬은 한번에 동작시킬 수 있는 프로세스의 갯수를 제한한다. 한계치는 우리가 쓰는 디바이스의 메모리 용량과 CPU 파워에 따라 달라진다. 그러나 Chrome이 한계에 도달하면 한 프로세스에서 동일한 사이트의 여러 탭을 실행하기 시작한다.

 

#메모리 절약하기 - 크롬의 서비스

이러한 접근이 브라우저 프로세스에도 동일하게 적용된다. Chrome은 브라우저 프로그램의 각 부분을 서비스로 실행하여 여러 프로세스로 쉽게 분할하거나 하나로 통합하는 작업이 가능하도록 아키텍처를 변경하는 작업을 진행하고 있다. 

 

이런 작업의 일반적인 아이디어는 Chrome이 강력한 하드웨어에서 실행될 때, Chrome은 각 서비스를 더 안정적인 프로세스들로 분할할수 있다. 그러나 리소스가 제한된 기기에 있는 경우 Chrome은 서비스를 하나의 프로세스로 통합하여 메모리 용량을 절약한다. 메모리 사용량을 줄이기 위해 프로세스를 통합하는 이러한 접근 방식은, Chrome에서 사용하기 이전에 Android같은 플랫폼에서 사용되었습니다.

 

다양한 서비스를 여러 프로세스 및 단일 프로세스로 이동시키는 Chrome의 기능 다이어그램

 

#프레임별 렌더러 프로세스 - 사이트 격리

사이트 격리는 각 교차 사이트 iframe에 대해 별도의 렌더러 프로세스를 실행하는 기능으로 최근에 Chrome에 의해 도입되었다. 우리는 지금까지 서로 다른 사이트간의 메모리 공간을 공유하는 단일 렌더러 프로세스에서 사이트 간 iframe을 실행할 수 있는 하나의 렌더러 프로세스를 각 탭에 할당하는 방식에 대해 이야기 했다. 같은 렌더러 프로세스에서 A 사이트와 B 사이트를 동시에 작동시키는게 문제가 없어보일 수 있다. 동일 출처 정책은 웹의 중심 보안 모델이다. 동일 출처 정책은 한 사이트가 동의 없이 다른 사이트의 데이터에 접근하는 것을 불가능하게 한다. 이런 동일 출처 정책을 우회하는 것이 대부분 보안 공격의 주요 목표이다. 사이트 격리는 사이트들을 분리하는 가장 효과적인 방법이다. Meltdown과 Spectre를 사용하면서 프로세스를 사용하여 사이트를 분리해야한다는 사실이 더욱 분명해졌다. Chrome 67부터 데스크탑 환경에서 사이트 격리가 기본적으로 활성화되어 있기 때문에 각 탭의 교차 사이트 iframe은 별도의 렌더러 프로세스를 가져온다.

사이트 격리 다이어그램. 사이트 내의 iframe을 가리치는 여러 렌더러 프로세스

사이트 격리를 가능하게 만드는 것은 다년간의 엔지니어링 노력이었다. 사이트 격리는 렌더러 프로세스를 할당하는것 만큼 간단한 작업이 아니다. 사이트 격리는 기본적으로 iframe이 교차 시이트들 간에 소통하는 방식을 바꿔놓는다. 다른 프로세스에서 실행되는 iframe이 있는 페이지에서 개발자 도구를 여는 것은 개발자 도구가 매끄럽게 보일 수 있도록 백그라운드 작업을 구현해야 한다는 것을 의미한다. 페이지 내에서 단어를 찾기 위해 Ctrl F를 사용하는 것 조차 서로 다른 렌더러 프로세스를 교차하는 작업을 거쳐야 한다. 이제 우리는 이런 사이트 격리에 대해 알아봄으로써 브라우저 엔지니어들이 사이트 격리가 궁극적인 도달점이라고 말하는 이유를 알 수 있다.

 

#마무리

이 글을 번역하면서도 역시 모르는 용어들이 많았다. 내가 이해한 것을 중심으로 말을 새로 사용해 정리해보겠다.

 

샌드박싱: 외부 출처의 파일을 보호된 영역에서 미리 실행시켜 위험성을 방지하는 기술

iframe: iframe이란 내부 프레임이라는 뜻으로 하나의 HTML문서에서 다른 HTML문서를 보여주고자 할때 사용하는 요소. 브라우저 특성상 iframe을 사용함.

플러그인: 컴퓨터의 추가 프로그램을 설치하여 특정 기능을 수행할 수 있도록 하는 소프트웨어.

 

모르는 용어는 이정도지만 다른 글들도 구글링하면서 작성한 글이다. 확실히 단순히 코드를 작성해서 웹페이지를 만드는 것과, 그 기반이 되는 기술들을 이해하면서 만드는 것은 다르다는 것을 느끼게 되었다.

앞으로도 전공지식과 코딩을 함께 성장시키는 개발자가 될 수 있도록 노력해야겠다!