Android Performance Patterns: Android UI and the GPU

콜트 맥안리스: 좋은 앱을 만들기 위해서는 내부적으로 어떻게 작동되는지 알고 있어야 하지요 하드웨어 레벨에서 어떻게 돌아가는지 모른다면 효율적인 앱 만들기는 영 힘들겁니다

저 콜트 맥안리스가 앱 렌더링에 대해 알려드리죠 안드로이드가 GPU를 어떻게 사용하는지 안다면 앱 실행 상의 문제를 해결하는데 큰 도움이 되지요 가장 중요한 문제는 앱의 작업 결과가 스크린에 어떻게 보여지느냐 골치아픈 XML과 여타 마크업 언어가 유저가 보고 바로 이해할 수 있는 픽셀로 어떻게 전환되느냐 하는 것이죠 래스터화, 흔히 이미지화라고 하는 프로세스 덕분에 가능한 것인데요 문자열이나 버튼이나 패스나 각종 형태를 그러니까, 하이 레벨 언어의 오브젝트를 텍스쳐나 화면의 픽셀로 바꾸는 겁니다

문제는, 래스터화는 시간을 무지하게 잡아먹는 프로세스입니다 그래서 그 과정을 좀 더 빠르게 해주는 하드웨어가 기기 안에 들어있죠 그래픽 처리 유닛, 줄여서 GPU 90년대에 보급이 시작됐는데요 래스터화를 가속시켜 줍니다 GPU 자체는 기본 자료형, 주로 폴리곤과 텍스쳐를 써서 이미지를 나타내죠 이걸 GPU가 스크린에 그릴 수 있게 앱의 작업 결과를 넘겨 주는 게 CPU다 이거죠

안드로이드에서 이걸 하는게 오픈GLES라는 API인데요 앱 UI에 버튼이나 패스나 체크박스 등 오브젝트가 화면에 그려져야 할 때는 먼저 CPU에서 폴리곤과 텍스쳐로 변환, 그런 후에야 GPU에 넘겨져서 래스터화가 됩니다 그리고, 아마도 짐작하시겠지만 이 UI객체를 폴리곤과 텍스쳐로 전환하는 과정은 절대 빠를 수 없는 작업입니다 CPU에서 GPU로 넘겨주는 것도 시간걸리는 일이고요 그럼 오브젝트를 전환해야 하는 횟수와 CPU와 GPU간의 넘겨주기의 횟수를 최소화하는 게 답이죠

참 다행스럽게도,오픈 GLES API는 GPU에 자료를 보내고 보존할 수 있게 해줍니다 만약 똑같은 버튼을 다시 쓴다 하면 이미 GPU의 메모리에 메시가 있으니 오픈GL에 그리는 방식만 지정해 주면 됩니다 그러니까 기본 룰은, GPU에 데이터를 최대한 많이, 빠르게 보내고, 거기 놔둬요 최대한 오랫동안 데이터 수정이 없도록 GPU에 이미 있는 데이터를 다시 보내면, 시간만 잡아먹는 게 되잖아요? 안드로이드 시스템은 효율적인 렌더링에 목숨걸었습니다

예로 들면, 앱에서 쓰는 리소스는, 비트맵하고 나머지 그릴 거 말입니다 하나의 텍스쳐에 합해져서 GPU에 자동으로 넘겨지죠 동시에 9-패치 같이 자주 쓰이는 폴리곤 메시도요 이미 넘긴 리소스를 쓰는 화면을 그릴 때마다 폴리곤 전환을 할 필요가 없어요 그러니까 이미 GPU에 데이터가 다 들어 있어서 화면 그리기가 정말로 빨라지는거죠 하지만 UI 객체가 더 복잡해질 수록 이 프로세스도 복잡해집니다 예로 들면, 이미지 띄우는 건 CPU에 있는 이미지를 메모리로 옮겨서 다시 GPU로 넘겨주고 그리게 하는 건데요

여기서 패스를 쓰면 CPU에서 폴리곤을 줄줄이 만들어줘야 할 수도 있어요 악몽입니다 아니면 그 형태를 마스킹하는 폴리곤을 GPU에서 만들어야 하죠 텍스트 렌더링은 생각하기도 무서운데요 CPU는 문자를 텍스쳐로 래스터화해서 그걸 GPU에 보내줘야 하고 그걸 문자열의 문자 수만큼 반복해야 하죠

GPU 메모리에 있는 문자를 사각형으로 렌더링하게요 애니메이션은 이걸 여기서 더 꼬이게 합니다 그러니까, 비쥬얼을 어떻게 바꾸느냐에 따라서 GPU의 데이터를 새로 처리하는 코스트를 프레임 하나 하나마다 계속 계속 부담할 수 있습니다 이건 GPU 문제의 빙산의 일각인데요 안드로이드는 매 프레임마다 앱 화면을 전체를 갱신할 필요 없이 실제로 변경된 부분만 새로 그려서 발생 부담을 획기적으로 줄여 줍니다

물론, 안드로이드가 해야 하는 래스터화 전 CPU의 전환이나 넘겨주기 작업도요 하지만 여기서 주의할 점이 있습니다 유저가 앱을 순조롭게 사용하려면 코드 갱신, GPU 데이터 갱신 그리고 렌더링까지 매 프레임 16 밀리세컨드 그 안에 해내야 합니다 적어도 목표는 그러하니까 이 안드로이드 퍼포먼스 패턴 시리즈 나머지를 보셔서 앱의 렌더링이 매끈하게 흘러가도록 하셔야 하는 거죠 그리고 저희 구글+ 커뮤니티에 들리셔서 개발자 분들의 팁이나 충고 보시는 것도 잊지 마시고요 그리고 항상 침착하게, 코드는 단정하게 실행은 효율적으로, 잊지마세요