2015년 5월 25일 월요일

[Lib] Android Home Button Event Disable 처리 하는 Lib들 (안드로이드 홈 버튼 이벤트 무시)

 1. Android Home Button Event

  • 안드로이드 홈 버튼 이벤트는 어플리케이션 레벨에서 제어가 불가능하다
  • 엑티비티등으로 처리할 경우 무조건(거의) 홈 이벤트를 받게 되어져 있다.

2. Disable Home Button Event Lib

  • 안드로이드 홈 버튼 이벤트를 무시처리하는 라이브러리가 존재한다.
    • 락스크린으로 예제가 구성되어져 있다.
    • SoftKey가 존재하는 단말(LG G시리즈, Nexus시리즈 등), SoftKey가 없는 단말(Samsung 갤럭시 시리즈) 두 조건에 모두 사용 가능하다.
    • SoftKey에서는 불안전한 모습이 보여지는데, 해당 이슈는 카카오톡의 카카오커버에서도 비슷한 양상을 보이고 있다.
    • SoftKey가 없는 단말(Samsung 갤럭시 시리즈)에서만 작동한다고 명시되어져 있다.

*** 필요에 따라 참고 활용 하면 될 듯 싶다.

04. NEON의 기본 개념 (작성중...)

* 위 블로그는 스터디를 정리한 것이므로 참고용으로만 사용하시길 바랍니다.

    1. NEON의 자료형


    {0, 1}을 통해 두 개의 다항식을 더하는 연산은 비트 단위는 배타적 OR(XOR)와 같고, {0, 1}을 통해서 
    두 개의 다항식을 곱하는 연산은 정수 곱하기와 같다.

    2. NEON 벡터의 크기

        A. NEON 벡터(변수)는 레지스터와 연결되어 있으며, NEON 함수는 레지스터를 제어하기 위해서 사용된다. 다음은 벡터의 종류와 크기를 정의한 것이다.

        B. 더블 워드 (64bit) NEON 벡터 (D 레지스터)

    • 8개의 8비트 요소
    • 4개의 16비트 요소
    • 2개의 64비트 요소
    • 1개의 64비트 요소

        C. 쿼드 워드 (64bit) NEON 벡터 (Q 레지스터)

    • 16개의 8비트 요소
    • 8개의 16비트 요소
    • 4개의 32비트 요소
    • 2개의 64비트 요소

        D. NEON 벡터 형태인 더블 워드 NEON 벡터는 D 레지스터와 연결되어 있고, 쿼드 NEON벡터는 Q레지스터와 연결되어 있다. 더블 워드 NEON 벡터는 64bit 크기의 연산을 지원하고 쿼드 워드 NEON 벡터는 128bit 크기의 연산을 지원한다.


        E. NEON 벡터는 NEON함수의 동작이나 연산으로 얻은 결과를 같은 형태의 NEON벡터에 대입할 수 있고, 다른 형태의 NEON 벡터에도 대입할 수 있다. 
        F. 즉, 더블 워드 벡터를 더블 워드 벡터에, 쿼드 워드 벡터를 쿼드 워드 벡터에 대입할 수 있으며, 더블 워드벡터를 쿼드 워드 벡터에, 쿼드 워드벡터를 더블 워드 벡터에 대입할 수도 있다. 

 3. NEON 레지스터

        A. NEON에서는 Q 레지스터 16개와 D 레지스터 32개를 포함하여 총 256 byte의 레지스터를 사용하여 연산한다. 
        B. 256 byte중에서 D레지스트는 VFP(부동 소수점) 레지스터와 공유한다. 
        C. NEON은 D레지스터를 VFP레지스터와 공유하므로 NEON 연산과 VFP 연산을 동시에 사용하면 레지스터가 충돌하여 예상하지 못한 결과가 발생한다.





2015년 4월 7일 화요일

03. JNI의 이해

* 위 블로그는 스터디를 정리한 것이므로 참고용으로만 사용하시길 바랍니다.

    1. JNI란

    • Java Native Interface의 약어로 자바코드가 자바VM에서 동작할 때, 네이티브 언어로 작성된 코드를 자바에서 사용하거나, 네이티브 언어에서 자바의 클래스와 메서드를 사용할 수 있게 해주는 프로그래밍 인터페이스이다.
    • 여기서 네이티브란 원시 코드라는 의미로 C/C++ 또는 어셈블리어 이다.
    • JNI로 작성된 네이티브 코드는 달빅 VM을 거치지 않고 CPU가 바로 실행한다.
    • JNI는 라이브러리가 아니라 인터페이스 이므로 C/C++과 자바 사이의 함수나 메서드 호출에 문제만 없게한다.
    • 인터페이스 규칙에 따라서 자바의 메서드와 C/C++의 함수를 정의함으로써 자바와 C/C++ 서로 간에 함수를 호출할 수 있게 된다.
    • 자바가 제공하는 플랫폼 이식성을 잃게된다.
    • 자바의 기능 중 하나인 type checking, garbage collection과 같은 안정성을 잃게된다. 
    • 자바에서 네이티브 메서드를 사용하려면 동적 라이브럴리들을 호출해야 한다. 이는 자바 시큐리티 매니저에 반대되는 연산이다.
    • 코드 자체가 방해물이 될 수 있다. (타이핑오류나 컴파일 오류를 종종 겪게 된다.)

    2. JNI 문법 

        A. 함수 이름은 반드시  <반환값>_Java_<패키지명>_<클래스명>_<메서드명> 이어야 한다.
        B. 함수 인수의 첫 번째는 꼭 JNIEnv여야 하며, 두 번째는 jobject여야 한다.
        C. cpp로 작성하였다면 extern "C"를 선언해야한다.
        D. JNIEnv* env와 jobject thiz는 JNI로부터 받은 변수 이므로 함수 인수에 꼭 사용해야 한다.
        E. 포인터 env는 JNI에서 가장 중요한 포인터로, 자바 VM에 대한 인터페이스를 포함하는 구조체의 포인터이다.
        F. 포인터 env에는 JNI의 환경 정보가 포함되어 있고, 자바 VM과의 상호작용 및 자바 객체와의 연계에 필요한 모든 기능을 포함한다.
        G. 변수 thiz에는 포함된 클래스의 정보가들어 있다. 이 예제에서 thiz는 stringFromJNI() 함수를 포함하는 HelloJni의 클래스를 참조한다.
        H. 만약 인수가 추가된다면 env와 변수 thiz 다음에 선언하여 사용한다.
         I. 라이브러리 Symbol은 항상 C 형식으로 있어야한다. C++로 작성했다면 extern "C"로 함수를 감싸서 C 형식으로 변경해야한다.
        J. c++ 형식일 경우env 포인터를 이용하여 멤버 함수를 호출할 때 멤버 함수에 env포인터를 전달 하지 않아야한다.

[네이티브 C코드 hello-jni.c]
#include 
#include 

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
{
#if defined(__arm__)
  #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
      #define ABI "armeabi-v7a/NEON"
    #else
      #define ABI "armeabi-v7a"
    #endif
  #else
   #define ABI "armeabi"
  #endif
#elif defined(__i386__)
   #define ABI "x86"
#elif defined(__mips__)
   #define ABI "mips"
#else
   #define ABI "unknown"
#endif

    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
}

[네이티브 C++코드 hello-jni.cpp]
extern "C"
{
jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
{
#if defined(__arm__)
  #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
      #define ABI "armeabi-v7a/NEON"
    #else
      #define ABI "armeabi-v7a"
    #endif
  #else
   #define ABI "armeabi"
  #endif
#elif defined(__i386__)
   #define ABI "x86"
#elif defined(__mips__)
   #define ABI "mips"
#else
   #define ABI "unknown"
#endif

    return env->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
}
}

    3. 자바에서 JNI 호출 

        A. 호출하는 함수 앞에 native를 붙인다
        B. loadLibrary() 함수로 라이브러리를 호출한다.
        C. 라이브러리의 이름에서 Lib와 .so는 붙이지 않는다.
public class HelloJni extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);
    }
   
    public native String  stringFromJNI();
    
    public native String  unimplementedStringFromJNI();
    
    static {
        System.loadLibrary("hello-jni");
    }
}

    4. JNI 자료형 선언 

        A. 자바에서 선언한 변수 자료형에 따라서 네이티브 코드에서 사용하는 변수와 이름이 달라진다.
        B. 네이티브 코드에서 int나 char와 같은 자료형이 사용될 때 자바에서 건너온 자료형이라는 것을 명시하기 위해서 자료형 앞에 j를 붙인다.
        C. 자바에서 건네받은 int는 jint가 된다. 자바에서 선언한 배열은 변수 자료형 뒤에 Array라는 문자가 붙는다. 예를 들어 자바의 char[]는 네이티브 코드에서 jcahrArray가 된다. jcharArray와 같은 배열을 네이티브코드에서 사용하려면 JNI의 변환 함수를 이용해야한다.
        D. Class -> jClass
        E. Throwable -> jThrowable

jint Java_com_example_hellojni_HelloJni_AddValue(JNIEnv* env, jobject thiz, jint a, jint b) 
{
    return a+b;
}


       

     5. JNI 배열

            A. C언어에서 배열은 연속한 메모리에 값이 설정되지만, 자바의 배열은 메모리가 연속해서 존재하지 않는다.
            B. 자바 배열을 C 배열에 맞게 변환해야 JNI에서 사용이 가능하다.
            C. C/C++에서 자바 배열에 접근하려면  Get<Type>ArrayElements() 함수를 사용하여 자바 배열을 C 형식의 배열로변환해야한다.
            D. 위의 함수는 자바 배열에 접근할 수 있는 메모리를 확보하고, 확보한 메모리의 포인터를 반환한다.
            E. 자바 배열의 사용이 끝나면 Release<Type>ArrayElements() 함수로 확보된 메모리 영역을 해제한다.

jint *carr; 
carr = )*env_->GetIntArrElements(env, arr, NULL);
//arr은 인자로 넘겨받음

//Do something...

(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
 

   6. JNI에서 자바 클래스와 함수

            A. JNI의 리플랙션을 이용하여 C/C++에서 자바 클래스와 함수에 접근한다.
            B. 리플랙션이란 애플리케이션이 실행될 때 자바 클래스에 접근할 수 있는 기능으로, 애플리케이션이 실행될 때 자바의 클래스나 메서드를 지정하여 애플리케이션의 유연성을 높일 수 있다.
            C. 실행과정은 다음과 같다
                (1) Class 찾기 - findClass() 또는 GetObjectClass()함수
                (2) 함수 ID 찾기 - 크래스에서 함수 이름과 인수 지정
                (3) 함수 호출

       6.1 Class 찾기 

            A. C/C++에서 자바의 클래스나 함수를 호출하려면 먼저 사용하고자 하는 Class를 찾아야한다. 이를 위해서 JNIEnv에서 FindClass(), GetObjectClass()함수를 제공한다.

       6.2 함수(Method) ID 또는 변수(Field) ID 찾기

            A. JNIEnv 에서는 GetMethodID()GetStaticMethodID() 함수를 제공한다.
            B. 함수를 찾으려면 시그니처(Signature)의 조합을 입력해야한다.
            C. 시그니처는 JNI에 존재하는 독특한 형태로 함수 이름, 인수, 반환값을 지정하여 유일한 함수로 만들 때 사용된다.



            D. int는 I로 정의되는것을 알 수 있다. 다만 클래스는 조금 특별한 문법을 가진다.
            E. 패키지를 포함한 클래스의 전체이름을 온점(.) 대신 빗금(/) 구분자로 변경한다. 그리고 제일 앞에는 'L'을 붙이고 제일 마지막에는 쌍반점(;)을 붙인다. 예를들어 'java.lang.String' -> 'Ljava/lang/String;'과 같이 변한다.

       6.2 함수 호출

            A. 클래스와 함수 ID를 찾았으면 Call<type>Method() 또는 CallStatic<type>Method()함수를 이용해서 해당 함수를 사용한다.

           [자바 코드]
private void func() {System.out.println("Hello");}


           [C 코드]

jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID funID = (*env)->GetMethodID(env, cls, "func", "()V");
(*env)->CallVoidMethod(env, obj, funID);

           B. 함수이름이 func이므로 GetMethodID의 3번째 인수로 'func'를 설정한다.
           C. 그리고 func()함수의 반환형은 void이고 인수를 사용하지 않으므로 ()이다.
           D. 자바의 멤버 변수도 리플렉션을 이용하면 C/C++에서 접근가능하다.

 7. 대용량 메모리 전달

            A. 자바에서 C/C++ 메모리를 전달할 때 배열을 사용한다.
            B. 이때 단순한 문자열 배열에서 부터 대용량의 이미지 데이터 배열을 전달하게 된다.

            C. 배열을 이용하면 작은 크기의 데이터에서는 속도가 떨어지지않지만, 대용량의 데이터에서는 속도가 떨어지게된다. 이는 자바 배열을 C/C++ 배열로 변환해야 하는데, 변환에 필요한 메모리를 확보하고 메모리를 복사하는 등 메모리를 변환하는 데 많은 시간이 걸리기 때문이다.

            D. 이럴 때에는 java.nio.Buffer 클래스를 이용하여 속도 문제를 해결할 수 있다.
            E. java.nio.Buffer클래스는 C/C++로 데이터를 전달할 때 배열과 같은 변환이 일어나지 않으므로 속도 저하가 거의 없다.



[자바코드]
void Java func(byte [] pixels) {
ByteBuffer buf = ByteBuffer.allocateDirect(10);
buf.order(ByteOrder.LITTLE_ENDIAN); //리틀 엔디안으로 변환
buf.put(pixels);
setBuffer(buf);
buf.get(pixels);
}

            F. 자바에서 allocateDirect() 함수를 사용하여 대용량 메모리를 확보하고, 해당 메모리를 리틀엔디안으로 변환한다.
            G. 자바는 기본적으로 빅 엔디안을 사용하고, 달빅 또는 ART는 리틀엔디안을 사용하므로 엔디안을 변환하지 않고 그대로 네티이트코드에 전달하면 예상하지 못한 겨로가같 나타난다. 따라서 엔디안 변환은 상당히 중요하므로 빼먹지 말아야 한다.

[C 코드]
void setBuffer(JNIEnv * env, jobject thiz, jobject buf)
{
    char* pixel = reinterpret_cast  (env-> GetDirectBufferAddress (buf));
    pixel[0] = 0; //데이터 가공
}


            H. C코드에서는 대용량 메모리를 전달받고, GetDirectBufferAddress() 함수를 이용해서 메모리의 시작 주소를 반환받는다. 그런 다음 개발자가 원하는 상태로 데이터를 가공하면된다.

            I. JNI 문법을 따로 더 익히자.

8. Android.mk 파일

          A. 안드로이드 Makefile은 리눅스에서 사용하는 GNU Makefile과 비슷하지만, 사용법은 훨씬 간단하다.
          B. Makefile은 소스 코드/헤더 파일 지정, 라이브러리 링크 등을 자동으로 해주고, 수정된 코드를 다시 컴파일하는 것을 편리하게 해준다.

          C. 안드로이드의 NDK는 이런 Makefile대신 Android.mk 파일로 컴파일 한다. Android.mk파일은 모듈을 만드는데 필요한 소스 코드와 링크할 라이브러리를 지정하거나 라이브러리의 이름을 지정하는 등 빌드에 필요한 최소한을 정의한다.

[Android.MK 샘플코드]

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)
--> Android.mk 파일과 같은 경로에 있는 hello-jni.c를 컴파일해서 libhello-jni.so라는 공유라이브러리를 생성하라

         D. LOCAL_CFALGS, LOCAL_CPPFLAGS :: 이것들은 APP_CFLAGS, APP_CPPFLAGS와 비슷하지만, Application.mk에 정의되는 APP_XXX변수가 모든 모듈에 적용되는 반면, LOCAL_XXX는 현재 모듈에만 적용된다. 실제로 Android.mk에는 최적화 레벨을 설정하지 말고 대신 Application.mk의 APP_OPTIM에 따를것을 권장한다.
       
         E. LOCAL_ARM_MODE는 강제로 ARM모드, 즉 32bit 명령어를 사용하여 바이너리를 생성하는데 사용된다. Thumb 모드(16bit 명령어)에 비해 코드 밀도가 좋지 않을 수 있지만, ARM 코드가 Thumb 코드보다 빠른 경향을 보이므로 성능이 개선될 수 있다. 예를들어 안드로이드의 Skia라이브러리는 ARM 모드로 명시적으로 컴파일 되었다. 만약 ARM모드를 사용하는 특정 파일들만 컴파일하고 싶다면, LOCAL_SRC_FILES에 .arm 접미사를 더해 해당 파일들을 리스트하면된다. 예를들면 file.c대신 file.c.arm으로 등록한다.

         F. LOCAL_ARM_NEON은 코드 내에서 Advanced SIMD 명령어 또는 intrinsic을 사용할 수  있는지, 그리고 컴파일러가 NEON명령어를 네이티브 코드에 생성할 수 있는가를 지정한다. NEON 명령어로 성능이 엄청나게 개선될 수 있지만 NEON은 ARMv7 아키텍처에서만 소개되었고 하나의 선택적인 컴포넌트 이다.

         G. LOCAL_DISABLE_NO_EXECUTE는 그 자체로는 성능에 어떤 영향도 주지 않는다. 하지만 고급 개발자라면 코드가 동적으로 생성될 때 NX bit를 비활성화 시키는 것에 관심을 가질 것이다.

[Android.mk 파일 분석 1]


[Android.mk 파일 분석 2]



8. Application.mk 파일

          A. Application.mk 파일도 애플리케이션에서 사용하는 라이브러리를 정의하는데 사용된다.
          B. 여러 개의 Android.mk파일에서 공통으로 사용하는 정의가 들어 있으며, Application.mk파일은 하나의 프로젝트에 하나만 존재해야한다.

          C. APP_OPTIM :: 옵션이며 release나 debug로 설정된다. 설정하지 않으면 애플리케이션이 디버그 가능핮니에 따라 설정된다.

          D. APP_CFLAGS(C/C++), APP_CPPFLAGS(C++ only) :: 컴파일러에 전달되는 플래그를 정의한다.
이 플래그들은 단순히 인클루드 파일을 찾기 위해 따라갈 경로를 지정해주는 정도로 사용될 수 있기 때문에 (ex: APP_CFLAGS += -I$(LOCAL_PATH)/myincludefiles), 코드를 최적화 하기 위해서는 반드시 필요하지은ㄴ 않다. 모든 플래그 리스트를 보려면 gcc 문서를 참조하도록하자

          E 성능이랑 관련된 플래그들은 -Ox시리즈(x는 전혀 최적화하지 않은 0에서 3까지의 최적화레벨을 지정), 또는 -Os이다. 하지만, 대부분의 경우 단순히 APP_OPTIM을 release로 저으이하거나 APP_OPTIM을 정의하지 않는 것으로 충분히 개발자를 위한 최적화 레벨이 설정되며, 이것만으로도 만족할 만한 결과를 얻을 수 있을것이다.

          F. APP_STL은 애플리케이션이 어떤 표준 라이브러리를 사용할지를 설정하기위해 사용된다.

[Application.mk 파일 분석 1]


[Application.mk 파일 분석 2]




2015년 4월 6일 월요일

02. 안드로이드 NDK의 이해

* 위 블로그는 스터디를 정리한 것이므로 참고용으로만 사용하시길 바랍니다.


    1. 안드로이드 NDK란


    • 안드로이드 네이티브 코드의 구성 요소를 포함하는 도구 모음 
    • 네이티브 코드는 C/C++ 또는 어셈블리어로 CPU가 바로 이해할 수 있는 코드를 말한다.
    • 컴파일러와 툴체인(링커 포함), 헤더파일, 라이브러리 등으로 구성됨
    • NDK는 SDK의 보조적인 역활을 한다
    • 아쉽게도 네이티브코드로 만들더라도 성능이 대폭 향상되지 않는다.
    • 실제로 최적화 되지 않는 네이티브 코드의 애플리케이션은 최적화된 자바 애플리케이션보다 실행시간이 더 걸릴수 있다.
    • 애플리케이션의 성능을 향상하려면 최적화된 함수를 이용하거나 포인터 연산 등을 활용해야한다.
    • 그리고 NEON과 같은 병렬 처리를 활용해야한다.

    2. 안드로이드 NDK의 기능 (Reveision 9 기준)

    • libc(C 라이브러리) 헤더
    • C++ 지원을 위한 최소 집합 헤더
    • limb(수학 라이브러리) 헤더
    • JNI 인터페이스 헤더
    • libz(Zlib 압축) 헤더
    • liblog(안드로이드 로깅)헤더
    • OpenGL ES 1.1 및 2.0 헤더
    • OpenSL/ES 고유의 오디오 라이브러리
    • libjnigraphics(픽셀 버퍼 액세스 헤더, 안드로이드 2.2 이상의경우)
    • 안드로이드 네이티브 응용 프로그램 API들

    3. JAVA와 NDK 애플리케이션의 실행차이

    • 자바 애플리케이션에는 달빅 VM이 해석할 수 있는 바이트코드가 포함되어 있고, 이 바이트 코드는 달빅 VM을 통해 네이티브 코드로 변환되어 애플리케이션이 CPU에 의해 실행되도록한다.
    • NDK에 의해서 만들어진 라이브러리는 애플리케이션 프레임워크와 달빅 VM을 거치지않고 실행된다. 이처럼 NDK는 프레임워크와 런타임을 거치지않고 실행되므로 애플리케이션 성능이 향상된다.

    4. NDK구성

    • GNUMakefile : 명령을 생성하는 유틸리티 makefile
    • ndk-build : ndk 빌드 명령어
    • ndk-gdb : 디버그 명령어
    • build : 빌드에 사용되는 도구 모음
    • doc : NDK에 관련된 문서 모음
    • platforms : 버전에 따른 API 헤더, 라이브러리 모음. API 레벨에 따라 이용할 수 있는 기능이 다름 상위 API는 하위 API의 기능을포함
    • samples : 예제프로그램 모음 
    • source : 자바 응용 프로그램 소스 코드
    • tests : 테스트 코드
    • toolcains : Cross compile에 필요한 도구 모음


01. 안드로이드와 병렬처리

* 위 블로그는 스터디를 정리한 것이므로 참고용으로만 사용하시길 바랍니다.


    1. 안드로이드 병렬 프로그램의 종류

    • ARM SIMD(NEON)
    • 안드로이드 멀티스레드(MARE, OpenMP)
    • 모바일 GPGPU(Open CL)

     2. ARM SIMD(NEON)

    • 일반적으로 어셈블리 명령어를 기본으로하며, C 언어 형식의 내장함수로 지원한다.
    • CPU의 명령어를 사용하므로 모바일 기기의 하드웨어 특성을 적게받는다.
    • 싱글코어 CPU에서도 빠르게 동작한다.
    • 병렬처리가 간편하다.
    • 벡터 변수의 데이터 크기는 64bit, 128bit 두개가 있다.
    • int8X8_t ~~ int32X2_t  (64bit)
    • int8X16_t ~~ int64X2_t (128bit)
    • SIMD 명령어 지원
    • 독립 레지스터(Q레지스터)
    • 독립 파이프라인
    • 정수와 부동소수점 기능을 모두 지원
    • 데이터 조작의 효율성이 높으며, 최소한의 메모리 접근이 가능
    • 광범위한 멀티미디어 코덱 개발 가능
    • CPU클록 수의 감소
    • 저전력
    • 애플리케이션 코드 효율의 증가

     3. 안드로이드 멀티스레드(MARE, OpenMP)

    • 공유 메모리 병렬 처리 기법을 말한다..
    • 자바의스레드, 퀄컴의 MARE등이 속한다.
    • 병행처리와 헷갈리면 안된다.
    • 기존코드를 재활용 할 수 있다.
    • CPU의 개수가 증가함에 따라 어플리케이션의 성능도 향상된다.

     4. 모바일 GPGPU(Open CL)

    • MIMD에 포함된다.
    • CPU보다 메모리의 용량이 크다
    • C 표준 컴파일러를 확장한 형태이다.
    • 콘텍스트 스위칭이 빠르다.

     5. NEON 애플리케이션의 동작구조

    • 메모리(배열) 변수에 있는 값을 벡터 변수에 대입한다.
    • NEON 명령어 또는 함수를 이용하여 벡터 변수 연산을 실행한다. 벡터변수 연산은 루프를 돌면서 반복해서 연산을 실행한다.
    • 벡터 변수에 저장된 결과를 메모리(배열) 변수로 저장한다.


     6. NEON 적용과정

    • 일반애플리케이션의 디버깅과 테스트를 완료해야한다. 일반 애플리케이션의 버그는 NEON에서도 발견된다.
    • 일반 애플리케이션의 병목 구간 또는 코어 부분을 확인한다.
    • NEON구조에 적당한지 확인한다.
    • 128bit, 64bit에 담을 수 있는 데이터의 개수를 설정한다.
    • 얼마나 성능이 개선될지 예측한다.
    • NEON 애플리케이션의 제작 및 디버깅 기간을 계산한다.
    • 제작하고 나서 NEON과 일반 애플리케이션의 성능을 비교한다.

    7. NEON 사용 방법

    • C언어
    • OpenMAX DL 라이브러리
    • 자동벡터화
    • 어셈블리어
    • 인트린식