본문 바로가기
Coding

Halide를 사용하여 Android에서 빠른 이미지 처리하는 방법

by flowsurfer 2022. 5. 22.
반응형

Halide를 사용하여 Android에서 빠른 이미지 처리하는 방법

 

나는 Halide를 사용하여 빠르고 유지 관리 가능한 코드를 작성하는 방법에 대해 썼습니다. 이것은 Android 애플리케이션으로 그 위력을 보여줄 것입니다.

Unsplash에 있는 Dan Smedley의 사진.

Halide는 최신 시스템에서 고성능 이미지 처리 또는 배열 처리 코드를 더 쉽게 작성하고 유지 관리할 수 있도록 설계된 오픈 소스 도메인 특정 언어입니다.

나는 Halide에 대한 시리즈를 작성해 왔으며 이 기사는 시리즈의 3번째 기사입니다. 지난 두 글에서 이야기한

이 기사에서는 Android에서 Halide를 사용하는 방법과 Halide가 제공할 수 있는 성능 향상에 대해 쓸 것입니다.

성능상의 이점을 보여주기 위해 다음의 문제 설명을 재사용할 것입니다. YUV 에게 RGB 색상 형식 변환. 나는 과거에 이 예제를 사용하여 이 예제를 사용하여 Android에서 이미지 처리를 수행하는 다양한 방법을 보여주는 몇 가지 기사를 작성했습니다.

면책 조항: 이 기사에서 언급된 모든 의견은 제 의견이며 제가 함께 일하는 조직의 의견이나 입장을 반영하지 않습니다.

저는 Google의 카메라에서 HDR 모드 및 야간 모드와 같은 기능을 작업합니다. 어려운 문제입니다. 리소스가 제한된 장치에서 복잡한 알고리즘으로 고해상도 이미지를 처리해야 합니다. Halide가 정말 빛나는 곳입니다!

Android에서 Halide를 사용하는 방법을 배우는 데 전적으로 관심이 있는 경우 이 하위 섹션을 건너뛸 수 있습니다.

Unsplash에서 Kir Simakov의 사진.

문제는 8MP(8 메가 픽셀 = ~ 8,000,000 픽셀) 이미지를 하나의 평면을 갖는 YUV_420_888이라는 특정 형식으로 변환하는 것입니다. Y 채널 및 2개의 반평면 서브샘플링 UV Android의 Bitmap에서 일반적으로 지원되는 ARGB_8888 형식으로 채널을 변환합니다. Wikipedia에서 YUV 형식에 대해 자세히 알아볼 수 있습니다. 또한 아래 기사에는 문제 설명이 더 잘 설명되어 있습니다.

내가 이것을 문제 진술로 선택한 이유는 YUV_420_888 Android Camera API에서 지원하는 가장 일반적인 OUTPUT 형식 중 하나이며 이미지는 일반적으로 다음과 같이 사용됩니다. Bitmap Android에서 — 따라서 이것을 상당히 일반적인 문제 설명으로 만듭니다.

저는 Android에서 이미지 처리 알고리즘이 어떻게 수행되는지 이해하기 위해 다양한 프레임워크/기술의 성능을 실험해 왔습니다. 나는 그것들을 서로 비교하기 위해 동일한 문제 진술을 사용했습니다. 다음은 내가 테스트한 다른 기술을 사용하여 동일한 몇 가지 예입니다.

Pixel 4A 기기에서 실행하여 위에 나열된 다양한 솔루션으로 문제 설명에 대해 다음 번호를 기록했습니다.

지금까지, RenderScript 기반 접근이 가장 빠른 것으로 관찰되었다. 그러나 RenderScript는 Android 12부터 더 이상 사용되지 않습니다. 여기에서 자세한 내용을 읽을 수 있습니다. 개발 팀은 새 하드웨어에서 훨씬 더 성능이 좋을 것으로 예상되는 몇 가지 대안을 공유했습니다.

다음 섹션에서는 이 문제에 대한 Halide 기반 솔루션을 공유하고 이 접근 방식을 사용한 벤치마크 결과를 살펴보겠습니다.

이전 기사 Halide에서 언급했듯이 일정에서 알고리즘을 분리할 수 있습니다. 먼저 YUV에서 RGB로 변환하는 알고리즘을 살펴보겠습니다.

이 경우 입력 이미지 형식이 YUV_420_888이라고 가정합니다. 이 이미지 형식의 몇 가지 주요 측면은

Luma 채널(Y 채널)은 전체 해상도 및 평면입니다.

  • 이는 Y-평면이 U/V 평면과 인터리브되지 않도록 보장됨을 의미합니다.

크로마 채널(UV 채널)은 서브샘플링되고 인터리브될 수 있습니다.

  • 서브샘플링은 4개의 Y 픽셀에 대해 하나의 UV 픽셀이 있음을 의미합니다.
  • 인터리브를 통해 UV 데이터를 UVUVUVUVUVUV 이미지의 각 행에 대한 메모리의 패턴입니다.

지금까지의 예에서, ARGB 출력에는 각 채널이 있습니다(R 또는 G 또는 B 또는 A = alpha) 와 함께 uint8 단일에 저장된 데이터 int32 값. 우리는 계속 같은 일을 할 것입니다.

할로겐 생성기는 다음과 같이 보일 수 있습니다.

YUV에서 RGB 색상 변환을 위한 할로겐 생성기

Halide에서 명시적인 일정을 작성하지 않으면 모든 것이 인라인으로 계산됩니다. 일정 작성에는 Halide, 대상 하드웨어 및 일정 수준의 적중 및 시험에 대한 전문 지식이 포함되는 경우가 많습니다. IMO, 첫 번째 단계는 항상 벤치마크를 작성하고 대상 하드웨어에서 실행하는 것이어야 합니다. 이를 위해 google/benchmark에서 오픈 소스 벤치마킹 프레임워크를 사용할 수 있습니다.

첫 일정부터 시작하자

기본 일정

YUV에서 RGB 할로겐으로의 기본 일정

이것은 각 픽셀에 대한 두 개의 for 루프 내에서 모든 계산을 인라인으로 수행합니다.

Pixel 4A에서 실행하면 위에서 언급한 생성기에 대해 다음과 같은 결과가 나타납니다.

이 숫자는 표준 네이티브 코드로 얻은 것과 유사합니다. 그러나 Halide로 짜낼 수 있는 숫자에 대한 기대치가 더 높습니다.

분할, 병렬화 및 벡터화

이러한 기본 요소에 대해 자세히 알아보려면 이 시리즈의 기사 2인 Halide 프로그래밍 언어의 일반 개념 이해를 참조하세요.

YUV에서 RGB 할로겐으로 최적화된 일정

이 일정은 루프를 더 많은 부분으로 분할하고 명령을 벡터화합니다. xi 루프 및 병렬화 y 고리. 벤치마크 결과를 보자

팔! 기본 일정보다 엄청나게 빨라진 속도가 보이시나요?

시간을 줄이는 것과 같은 추가 최적화가 가능할 수 있습니다. uv_centered 계산되거나 다른 분할 요소를 시도하고 있지만 지금까지는 좋아 보입니다.

위에서 언급한 생성기는 다음과 같은 C++ 메서드를 생성합니다.

YUV to RGB Halide 생성기 생성 방법

에서 직접 사용할 수 있는 C++ 라이브러리 또는 JNI 코드.

앞으로 필요한 경우 Android 스튜디오에서 Halide를 설정하고 종단 간 사용하는 방법에 대해 쓸 것입니다. 댓글을 통해 도움이된다면 LMK.

모든 것을 함께 연결하려면 전체 엔드 투 엔드 파이프라인을 연결해야 합니다.

Java --> JNI --> Halide --> Java --> Bitmap

이는 전체 대기 시간으로 이어집니다. ~28ms. 따라서 지금까지 고려한 다양한 접근법의 결과를 살펴보면

Halide 구현을 나타내는 최신 결과는 기존 결과와 가장 빠르고 업데이트된 비교입니다.

이것은 우리에게 고성능과 유지보수가 쉬운 코드를 제공합니다! 엔지니어링 팀이 원하는 것은 무엇입니까?

이 문제에 대해 훨씬 더 빠른(약 ~12ms의 대기 시간) 다른 솔루션을 찾았지만 하드웨어별 구현(NEON 내장 활용)과 병렬 처리 등을 모두 필요로 합니다. 작성하거나 유지 관리하는 것이 쉽지는 않지만 나중에 기사를 쓸 가치가 있습니다.

매우 효율적인 코드를 작성하는 사람들은 코드를 작성하는 데 소비하는 시간보다 코드 최적화에 최소 2배의 시간을 소비한다고 말합니다.

— 인터넷의 어떤 것

Halide를 사용하면 다양한 일정을 훨씬 쉽게 시도하고 조정할 수 있습니다. 루프 순서, 논리 분할, 스레딩 등을 수동으로 변경하는 것보다 쉽고 ABI 특정 벡터화된 코드를 작성하고 유지 관리하는 데 따른 고통을 제거합니다.

Halide, Auto vectorized C++ 코드와 같은 접근 방식은 이식 가능하고 유지 관리가 더 쉽습니다.

  • 명시적으로 손으로 조정한 CPU 특정 코드와 비교하여

항상 최적화하기 전에 사용 사례를 고려하십시오.

  • 예 — 라이브러리 개발자 대 앱 개발자
  • 전체 작업에 2초가 걸리는 경우와 같은 실제 병목 현상을 이해하고 28 ms 그리고 12 ms 큰 이점을 제공하지 않을 수 있습니다.

애플리케이션이 성능에 중요한 경우: 벤치마크 → 분석 → 최적화(반복)

반응형

댓글