하드웨어 가속이 뭐야?

GY·2024년 2월 27일
0

Basic CS

목록 보기
27/28

FE에서 애니메이션 구현 시 신경써야 할 점

프론트엔드 개발자라면 애니메이션 구현은 당연하게 하게 되는 업무 중 하나인데요,
단순한 애니메이션도 성능 측면에서 신경써야 하는 부분들이 분명히 존재합니다.

전통적으로 브라우저는 웹 페이지 콘텐츠의 렌더링을 대부분 CPU에 의존했습니다. 하지만 최근에는 휴대용 기기에도 GPU가 기본으로 포함되고, 비디오나 3D 그래픽과 같은 콘텐츠의 사용이 늘면서 GPU를 활용해 웹 페이지의 콘텐츠를 렌더링하는 방법을 고민하게 됐습니다.
출처: Naver D2 - 하드웨어 가속에 대한 이해와 적용


하드웨어 가속?

다소 생소한 표현인데, 왜 하드웨어 가속이라 할까요?
이 개념을 한 문장으로 풀어써볼 수 있을 것 같습니다.

CPU에서 처리해야 했던 요소들을 GPU(하드웨어)가 처리하도록 해 작업의 속도를 높이는 (가속) 것

더 구체적으로 이야기 해보자면, 아래에서 더 설명하겠지만,

GPU를 이용해
graphics layer 단위로 렌더링된 이미지를
✅ 한 장의 이미지로 합성해서 화면에 출력하는 기술을 말합니다.


이에 대해 이해하기 위해,

  • CPU와 GPU는 무엇이고 어떤 역할을 하는지
  • graphics layer는 무엇인지
  • 이미지를 합성해 화면에 출력하기까지 이와 관련해 어떤 과정을 거치는지

에 대해 정리해보게습니다.


먼저 GPU와 CPU에 대해서 짚고 넘어가볼게요.


CPU와 GPU

CPU (Central Processing Unit) 는 컴퓨터 시스템을 통제하고 프로그램의 연산을 실행/처리하는 가장 핵심적인 컴퓨터의 제어 장치입니다.

GPU (Graphic Processing Unit)는 말 그대로 그래픽을 처리하도록 제작되었습니다. 이미지와 영상, 비디오 렌더링과 같은 처리를 대신해 CPU의 부하를 줄여주는 역할을 합니다.

하드웨어 가속은, 이 GPU를 사용해 필요한 영역의 레이어를 별도로 생성해 렌더링을 담당하도록 만듦으로써 CPU의 부하를 줄여 효율적으로 렌더링하도록 하는 것을 말합니다.


Paint Layer와 Graphics Layer

하드웨어 가속을 사용하면 Paint layer가 아닌 graphics layer를 별도로 생성해 작업하게 됩니다.
각 레이어에 대해 알아보기 전에, 이 레이어를 생성하는 시점을 먼저 알아볼게요.

아래는 브라우저 렌더링 과정을 나타낸 도식표입니다.
두 번째는 조금 더 간단히 도식화한 표에요.

Life of a Pixel / 출처 : https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y/edit#slide=id.ga884fe665f_64_1800
본 콘텐츠를 무단으로 복사 후 게재 혹은 배포할 시 저작권법에 의거하여 처벌받을 수 있음을 명시합니다.
출처 : https://ssocoit.tistory.com/259 [코딩하는 경제학도]
Copyright © SsocoIT


우리가 잘 알고 있는 Critical Rendering Path 에서
렌더트리 생성 후 layout > paint 단계를 거칠 때, 그 사이에 레이어 트리를 업데이트 하는 과정을 거치게 됩니다. 그 뒤 만들어진 레이어들을 합성하는 composite 단계를 진행하게 되죠.

정리하면 렌더트리 생성 > layout > 레이어 트리 업데이트 > paint > composite의 과정을 거치게 된다고 할 수 있습니다.

이 레이어 트리를 업데이트 하는 과정에서 위에서 이야기한 레이어를 다루게 됩니다.

레이어 트리 업데이트

레이어 트리 업데이트는 렌더트리의 결과물 중에서 렌더링에 사용되는 부분을 레이어로 만들어 주는 과정입니다.
이 단계에서 생성하는 레이어는 paint layergraphics layer 2가지로 나뉩니다.

Paint layer

CPU는 critical rendering path에서 생성되는 렌더트리를 이용해 화면에 표시될 레이어를 생성합니다. 이 레이어를 paint layer, 혹은 render layer라고 부릅니다.

critical rendering path에서 만드는 레이어는 DOM 요소를 효율적으로 표시하도록 하는 역할을 합니다. 일반적으로 동일한 좌표 공간을 가지는 요소들은 같은 Paint layer에 위치하도록 만드는 것이죠,. 하지만 필요에 따라 몇 가지 특수조건을 만족하면 추가 레이어를 생성해 별도로 요소를 준비합니다.

이렇게 새로운 paint layer가 생성되는 경우는 다음과 같이 여러가지가 있습니다.

  • Root Element인 경우 (Root Element에 대해서는 Root Layer가 생성)
  • 명시적인 position 속성값을 가지고 있는 경우 (relative, fixed, sticky, absolute)
  • 투명도가 1 미만인 경우
  • filter, mask, transform, mix-blend-mode를 가진 경우
  • backface-visibility attribute가 hidden인 경우
  • auto가 아닌 column-count, column-width 속성을 가진 경우
  • reflection 속성을 가진 경우
  • 브라우저가 내부적으로 생성하는 경우

grphics layer

앞서 하드웨어 가속이란, CPU 대신 GPU를 사용해 화면에 요소들을 출력하는 것이라 이야기했습니다.
이 경우 paint layer 대신 GPU가 graphics layer를 각각 생성하고 이를 묶어 하나의 이미지로 합성해 출력하게 된다고 했죠.

그래픽 레이어는 하드웨어 가속 처리를 위한 물리적인 레이어로, GPU가 레이어별 renderObject를 이 그래픽 레이어 단위로 렌더링한 뒤 이를 합성하는 과정을 거칩니다.

paint layer에 속하는 요소 중 root노드, canvas, video 태그와 같은 노드들은 다시 graphics layer를 생성하게 됩니다.

이를 포함해, 그래픽 레이어가 생성되는 대표적인 조건들은 다음과 같습니다.

  • video나 canvas 태그를 사용하는 경우
  • 하드웨어 가속 플러그인을 사용하는 경우
  • 3d transform 속성이 존재하는 경우
  • 하드웨어 가속이 된 2D canvas 요소인 경우
  • backface-visibility attribute가 hidden인 경우
  • transition, animation 속성이 있는 경우
  • will-change를 설정한 경우 (opacity, transform, top, left 등..)

하드웨어 가속 적용 방법

그러면 하드웨어 가속은 어떻게 적용해볼 수 있을까요?
여러 대표적으로 2가지 방법이 있습니다.

layer hack

translate3d와 같은 css 3d 속성을 적용해주면 해당 요소는 별도의 graphics layer로 분리되어 렌더링 됩니다.

📍 그런데 이러한 속성을 부여해 하드웨어 가속을 사용하는 것은 사실, layer hack으로 볼 수 있습니다. 일종의 편법같은 방법인 것이죠.

다른 방법이 없다면 사용할 수 있지만, 그 보다 이를 위해 도입된 will-change를 사용하는 것을 고려해보는 것이 좋습니다.

will-change

기존의 layer hack을 대체하기 위한 방법으로 사용할 수 있는 새로운 Css 모듈 명세입니다.

미래에 변경이 발생할 속성에 관해 브라우저에 힌트를 주는 역할로, 브라우저가 해당 변경을 위한 작업을 사전에 최적화해 실제 변경이 발생되는 시점에 더 빠르게 업데이트할 수 있도록 합니다. 또한 보다 효율적으로 graphics layer를 생성하도록 합니다.

will-change를 사용할 때는 현재 변경이 발생하고 있는 시점이 아니라, 발생할 시점의 속성을 지정해야 합니다.

또한 변경이 완료된 이후에는 속성을 제거해야 합니다.

일반적으로 will-change 속성으로 지정되는 변경 작업은 많은 비용과 리소스를 사용하는 작업이 대부분입니다. 브라우저는 일반적으로 최적화 이후, 이 최적화를 위해 수행된 작업을 제거하고 다시 원래 상태로 돌아가는 동작을 수행합니다. 그러나 will-change 속성은 이러한 기본적인 브라우저 동작을 덮어쓰고 최적화된 작업을 일정시간 동안 내부적으로 유지하기 때문에, 불필요하게 오래 유지되지 않도록 작업이 끝난 이후에는 해당 속성을 제거해주는 것이 좋습니다.

단, 이후에도 동일한 액션을 사용자가 반복해 수행할 것이 예상되거나, 혹은 해당 영역에서의 인터렉션이 계속해서 사용되는 경우에는 해당 속성을 유지하는 것이 더 나은 성능을 얻을 수 있으니 경우에 따라 유지 여부를 고려하는 것이 좋습니다.


이 paint layer와 graphics layer를 사용해 화면에 요소를 출력하는 과정은 이렇게 정리해볼 수 있습니다.
  • render tree생성 > 필요한 경우 Render layer (Paint layer) 매핑
  • render layer 요소 가운데 GPU에 업로드되는 요소는 다시 graphics layer로 분리되며, 레이어 각각을 독립적인 소프트웨어 비트맵으로 출력한다
  • GPU에 텍스처로 업로드한다
  • 다양한 레이어를 화면에 표시할 최종 이미지로 함께 합성한다.

그림 1 DOM 트리와 RenderLayer, GraphicsLayer의 관계(이미지 출처: https://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome)

GPU에 이미지를 텍스처로 업로드하면 3차원 그래픽 표면에 보다 다양한 형태로 매핑할 수 있고, 위치 이동이나 변형 등 다양한 작업에 사용할 수 있습니다. 즉, 더 적은 비용으로 다양한 변형과 요소의 합성을 실행할 수 있게 됩니다.

단점 및 주의사항

하드웨어 가속은 속도 측면에서 이점을 누릴 수 있지만, 트레이드 오프를 잘 고려해 적용해야 합니다.

추가적인 메모리 사용

레이어를 별도로 분리해 생성하기 때문에 그만큼 추가적인 메모리가 발생합니다.

특히 요소의 속성값에 따라 영역이 커질 수 있으므로 주의해야 합니다. 예를 들어, text-indent 속성이나 left 속성에 -9999px과 같이 영역의 크기를 키워 화면을 지나치게 벗어나도록 값을 설정하면, 해당 영역의 크기가 늘어난 만큼 하드웨어 가속에 의해 구성된 레이어도 커지게 되고 그만큼 불필요하게 메모리를 많이 사용하게 됩니다.

따라서 하드웨어 가속을 적용하는 요소의 크기는 작을 수록 좋고, 갯수도 화면에서 5~6개로 구형하는 것이 좋습니다.


무분별한 사용 시 브라우저 성능 저하

돔 트리 자체를 변경하는 일이 많아지면 GPU의 레이어만으로 해결할 수 없기 때문에 하드웨어 가속으로 인한 비용만 누적되는 상황이 발생할 수 있습니다.

요소에 하드웨어 가속 속성이 부여되면 레이어로 분리되며, 이 레이어는 변경되는 내용이 없는 한 해당 요소를 GPU 메모리에 다시 업로드하지 않습니다.

해당 요소가 변경될 경우 GPU 메모리가 갱신됩니다.

이동이나 크기 변경이 자주 발생하는 영역에 하드웨어 가속을 적용하고, 이동이나 크기 변경작업의 경우 transform 속성을 사용하는 것이 좋습니다.


시간 비용 증가

CPU와 GPU가 처리해야 하는 데이터와 프로그램은 각각 분리되어 있기 때문에, 메인 메모리 RAM에 있는 요소들이 비디오 메모리 VRAM으로 전달하는 과정이 필요합니다.

이 때 전달하는 데 시간이 소요될 뿐 아니라, VRAM의 메모리 용량이 부족하다면 GPU가 필요한 태스크를 정상적으로 처리하지 못하는 상황이 발새할 수 있습니다.

따라서 기기에 따라 하드웨어 가속 적용여부를 다르게 설정하는 것 또한 고려할 필요가 있습니다.


화면 깜빡임 현상

요소에 하드웨어 가속 속성이 부여되면 대상 영역이 GPU에 업로드되는데, 이 때 해당 영역이 크면 화면이 깜빡이는 현상이 발생할 수 있습니다.


기기에 따른 성능 저하 가능성

기기에 따라 성능 저하 가능성이 있기 때문에 선별적으로 하드웨어 가속 적용이 필요할 수 있습니다.

따라서, 하드웨어 가속을 무조건 사용하는 것이 성능 최적화를 위한 최선의 방법이 아니라는 것을 인지하고, 다양한 부분에서 트레이드오프를 고려하는 것이 필요합니다.


Reference

https://ssocoit.tistory.com/259
https://d2.naver.com/helloworld/2061385

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글