'ARM'에 해당되는 글 2건

  1. 2013.10.31 [android] loadLibrary 와 CPU 특성
  2. 2013.06.14 libjpeg-turbo 에 대해서 알아 보자

[android] loadLibrary 와 CPU 특성

android 2013. 10. 31. 14:20

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Android에서 native 라이브러리를 만들 때 보통은 armeabi / armeabi-v7a 용으로 컴파일 해서 프로젝트의 libs 폴더 밑에 넣어준다. 이는 대부분의 안드로이드 장치가 ARM 기반의 CPU로 만들어 졌기 때문이다. 사실 Android 에서 지원하는 cpu ARM 뿐만 아니라 Interlx86 도 지원하고 MIPS 또한 공식적으로 지원한다. 다만 시장에 아직 제품이 많지 않을 뿐이다.

 

참고 : CPU Architecuture 별 지원 Platforms

Native Code CPU Architecture Used

Compatible Android Platform(s)

ARM, ARM-NEON

Android 1.5 (API Level 3) and higher

x86

Android 2.3 (API Level 9) and higher

MIPS

Android 2.3 (API Level 9) and higher

 

이번에 Intel에서 Xolo-X900 이라는 Intelx86 기반의 안드로이드 폰을 출시했다. 이번이라고 한건 내가 지금 알았기 때문이고, 찾아보니 실체 출시된 날짜는 2012 4월 쯤이었다. ~ 완전 모르고 있었네 ㅎㅎ

 

So 파일을 로딩하기 위해서 보통은 System.loadLibrary() 함수를 호출한다. 그러면 해당 함수가 알아서 CPU를 확인해서 알맞은 so 모듈을 로딩해주는 것으로 알고 있었다. 우연히 xolo 디바이스를 구할 수 있어서 armeabi/armeabi-v7a so 모듈만 있는 프로그램을 실행시켰는데, armeabi-v7aso 가 로딩 되는 것이다. 우와그러나 실행하다가 죽는다. ㅠㅠ  

 

그래서 loadLibrary를 연구해 보기 시작했다. 가장 먼저 developer의 문서를 찾아보면 아래와 같다.

Loads and links the library with the specified name. The mapping of the specified library name to the full path for loading the library is implementation-dependent.

loadLibrary(“foo”) 이렇게 호출하면 이름(foo)과 일치하면서, device의 CPU타입에 따라서 적절한 모듈을 로딩해 준다. 즉 해당 device armeabi-v7a 를 지원하면 lib/armeabi-v7a 경로에 있는 foo.so를 로딩한고 device x86을 지원하면 lib/x86 경로이 있는 foo.so를 로딩하는 것이다. 그리고 full path를 사용하면 해당 so를 직접 로딩한다는 말이다.

 

그럼, loadlibrary(foo)를 호출 했을 때 IntelXolo 단말기는 왜 lib/armeabi-v7a 경로에 있는 모듈을 로딩한걸까? ( lib/x86 폴더는 존재하지 않는 상태임 )

 

궁금증을 해결하기 위해서 일단 Java 레벨에서(NDK가 아닌) CPU 정보를 얻는 방법부터 찾아 보았다. 간단하게 Build 클래스에 정보가 있었다.

Build.CPU_ABI 를 이용하면 되는데, 보다보니 Build.CPU_ABI2가 존재 한다. ~~ 느낌이 온다~

(참고로 ABI는 Application Binary Interface의 약자다. ) 

 

System.loadLibrary  디바이스의 Build.CPU_ABI / Build.CPU_ABI2 의 순서로 so 모듈을 찾는 것이다. Android loadLibrary 내부에서 mapLibraryName을 호출하는 부분이 아마도 이 동작을 하는 것으로 추측된다.

 

해결 하려면 so 파일을 x86용으로 개발해서 빌드한후 추가하면 된다. 또는 모든 기능이 x86을 지원하는 것이 아니라면 아래처럼 Java 코드로 간단하게 막을수 있다.

public static void loadLibrary() {

      if (isLoaded) {

            return;

      }

 

      if (isLoaded == false) {

      if (Build.CPU_ABI.equals(“x86”)) {

            isLoaded = false;

            return;

      }

 

      try {

            System.loadLibrary("foo");

            isLoaded = true;

 

      } catch (Throwable e) {

            isLoaded = false;

}

}

추가로 발견한 내용으로는 프로젝트의 lib/x86 폴더에 해당 모듈이 하나라도 있으면 google play 마켓에서 x86용 디바이스에 노출이 된다는 점이다.

따라서 프로젝트가 x86을 부분적으로 지원 할 수는 없고 모든 so 모듈들을 x86으로 지원하는 것이 좋다.

 

 



:

libjpeg-turbo 에 대해서 알아 보자

개발 2013. 6. 14. 11:57

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

1. jpeg[1]란 무엇인가?

간단히 누구나 알고 있듯이 이미지 압축 형식중 하나인 것이다. 그런데 약자의 뜻도 모르고 있어서 한번 찾아 봤다.

Jpeg = joint photographic coding experts group

JPEG는 컬러 순간 동작(steal) 이미지를 위한 국제적인 압축표준으로 CCITT(Consultatve Committee International Telegraphand Telehpone) ISO에서 정의하고있다. JPEG는 이미지를 작은 블록으로 나누어 많은 양의 이미지 정보를 줄이는 DCT(Discrete Cosine Transformer) 알고리즘에 기초를 두고 있다. 압축률을 늘이기 위해서는 보다 많은 양의 이미지 정보를 지우고, 이에 따라 세세한 부분의 이미지가 줄어들기 때문에 이미지의 질은 낮아진다. 또한 이미지의 질이 낮아진 것을 느끼지 못할 정도까지만 압축시켰을 때 약 25:1의 압축률을 얻는다. 25MB의 이미지를 1MB로 줄일 수 있는 것이다. 비디오를 압축시키는데 사용되기도 한다. 각각의 프레임을 분리된 이미지로서 인트라프레임코딩(Intraframe Coding)이라 불리는 과정을 통해 각 프레임을 따로따로 압축시킨다. 이것은 다시 말해, 사용자가 비디오가 압축된 채로 독립적인 각 프레임을 랜덤 액세스할 수 있음을 나타낸다.

한글로는 정지영상 압축 포맷정도로 부를수 있다.

 

2. libjpeg-turbo[2]는 무엇인가?

Libjpeg-turbo  SIMD 명령( MMX, SSE2, NEON)을 사용해서 빠르게 인코딩/디코딩하는 JPEG 이미지 코덱이다.  SIMD Single Instruction, Multiple Data 로 하나의 명령으로 여러 개의 데이터를 처리하는 명령어 집합이다. 즉 하나의 명령어를 실행하는 동안 같은 오퍼레이션이 병렬로 데이터를 처리하여 속도가 빠른 것이다. 참고로 SSE2[3]2001년 인텔의 펜티엄 4에 처음 포함되었다. 그리고 NEON[4]ARM 프로세서에서 사용하는 SIMD 명령 지원체라고 보면 된다.

, libjpeg-turbo  intel 프로세서와 arm 프로세서에서 모두 동작가능한 빠른 jpeg 코덱인 것이다. 안드로이드에서 주로 사용하는 프로세서가 arm 아키텍쳐 기반이므로 흥미를 가질만 하다. 또한 최근 intel 에서도 모바일 프로세서를 삼성전자에 납품하여 갤럭시 탭 10인치에 시범적으로 사용된다고 하니, 앞으로 intelarm이 양분하는 모바일 프로세서 환경에서 딱 어울리는 녀석이다.

 

3. “libjpeg-turbo” != “TurboJPEG”

이름이 비슷해서 두개를 햇갈려 할 수 있는데 각각 어떻게 탄생하게 되었는지 알아보자

libjpeg-turbo은 기원은 libjpeg에서 속도를빠르게 하기 위한 libjpeg/SIMD 프로젝트서 시작되었다. ( libjpeg v6b, 2009) 현재는 독립된 프로젝트로 진행되면서 산업 표준으로 인정 받고 있다.

TurboJPEG“VirtualGL and TurboVNC” 그룹이 사용하려고 만든 API 이다.

 

4. 속도는 jpeg에 비해서 얼마나 빠를까?

다른 모든 조건이 같은 환경에서 테스트를 했을때, 평균적으로 2~4배 빠르다고 한다.

아래는 libjpeg-turbo 프로젝트 그룹에서 비교한 성능테스트 결과이다. [5]

 

libjpeg-turbo Speedup Relative to Other Codecs, Non-Grayscale Compression/Decompression (1.0 = equal performance)

 

libjpeg-turbo x86-64

libjpeg-turbo x86

 

Compression

Decompression

Compression

Decompression

libjpeg v6b

3.68 - 5.29

2.12 - 3.32

3.40 - 4.75

2.43 - 4.24

libjpeg v8d

3.66 - 5.79

1.95 - 3.85

3.19 - 5.22

2.29 - 4.96

Intel® IPP v7.1

0.922 - 1.21

0.811 - 1.18

0.710 - 1.10

0.650 - 1.26

 

Libjpeg 최신판인 v8d와 비교결과를 보면 평균적으로 2~5배 빠르게 나왔다 인텔의 IPP 와 비교했을때는 비슷하거나 오히려 조금 느리기도 하다. 돈있으면 인텔의 IPP를 사서 쓰는 것도 나쁘지 않을 것 같다. 다만 IPP는 인텔 프로세서에서만 실행된다는 점 !!

 

 

참고

[1] libjpeg : http://www.ijg.org/

[2] libjpeg-turbo : http://libjpeg-turbo.virtualgl.org/

[3] SSE2 : http://ko.wikipedia.org/wiki/SSE2

[4] Introducing NEON : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0002a/index.html

[5] libjpeg-turbo 성능 : http://www.libjpeg-turbo.org/About/Performance

 

 



: