developer tip

Dalvik 및 Android 툴체인에서 어떤 최적화를 기대할 수 있습니까?

copycodes 2020. 11. 11. 20:17
반응형

Dalvik 및 Android 툴체인에서 어떤 최적화를 기대할 수 있습니까?


저는 고성능 Android 애플리케이션 (게임)을 작업 중이며 먼저 가독성을 위해 코딩하려고하지만 내부에서 일어나는 일에 대한 그림을 마음 속에 간직하고 싶습니다. C ++를 사용하여 컴파일러가 나를 위해 무엇을 할 것인지,하지 않을 것인지에 대해 상당히 좋은 직관을 개발했습니다. Java / Android에 대해 동일한 작업을 시도하고 있습니다.

따라서이 질문. 웹에서이 주제에 대해 거의 찾을 수 없습니다. Java 컴파일러, Dalvik 변환기 (dx) 및 / 또는 JITter (Android 2.2 이상)가 다음과 같은 최적화를 수행합니까?

  • 메서드 인라인. 어떤 조건에서? private메소드는 항상 안전하게 인라인 될 수 있습니다. 이게 끝날까요? 방법은 public final어떻습니까? 다른 클래스의 객체에 대한 메서드? static행동 양식? 컴파일러가 객체의 런타임 유형을 쉽게 추론 할 수 있다면 어떨까요? 나는 등의 방법으로 선언해야 final또는 static가능하면?

  • 공통 하위 표현식 제거. 예를 들어 someObject.someField두 번 액세스 하면 조회가 한 번만 수행됩니까? 게터에게 전화하면 어떻게 되나요? 어떤 산술 식을 두 번 사용하면 어떨까요? 한 번만 평가됩니까? 값이 변경되지 않는 것으로 알고있는 일부 표현식의 결과를 for루프 의 상한으로 사용하면 어떻게됩니까?

  • 배열 조회에 대한 경계 검사. 툴체인은 전형적인 for루프 와 같은 특정 조건에서 이것을 제거 합니까?

  • 가치 인라인. 일부에 대한 액세스는 public static final int항상 인라인됩니까? 다른 수업에 있더라도? 다른 패키지에 있더라도?

  • 분기 예측. 이것이 얼마나 큰 문제입니까? 일반적인 Android 장치에서 분기가 큰 성능 저하를 일으키고 있습니까?

  • 간단한 산술. someInt * 2로 대체 someInt << 1?

기타 ...


JIT @ Google에서 일하는 엔지니어 중 한 명인 Ben입니다. Bill과 내가이 프로젝트를 시작했을 때 목표는 리소스 경합 (예 : 메모리 풋 프린트, 컴파일러 스레드에 의해 CPU 하이재킹)에 미치는 영향을 최소화하면서 가능한 한 빨리 작동하는 JIT를 제공하여 저가형 장치에서 실행될 수 있도록하는 것이 었습니다. 잘. 따라서 우리는 매우 원시적 인 추적 기반 모델을 사용했습니다. 즉, JIT 컴파일러에 전달 된 컴파일 엔티티는 기본 블록이며 때로는 단일 명령어만큼 짧습니다. 이러한 추적은 인터프리터 및 코드 캐시 조회가 자주 호출되지 않도록 연결이라는 기술을 통해 런타임에 함께 연결됩니다. 어느 정도 속도 향상의 주요 원인은 자주 실행되는 코드 경로에서 반복되는 인터프리터 구문 분석 오버 헤드를 제거하는 데 있습니다.

즉, Froyo JIT로 구현 된 몇 가지 로컬 최적화가 있습니다.

  • 레지스터 할당 (JIT가 Thumb 코드를 생성하므로 v5te 대상에 대해 8 개 레지스터 / v7에 대해 16 개 레지스터)
  • 스케줄링 (예 : Dalvik 레지스터에 대한 중복 ld / st 제거,로드 호이 스팅, 매장 싱킹)
  • 중복 null 검사 제거 (이러한 중복이 기본 블록에서 찾을 수있는 경우).
  • 단순 계수 루프에 대한 루프 형성 및 최적화 (즉, 루프 본체에 측면 출구 없음). 이러한 루프의 경우 확장 유도 변수를 기반으로하는 배열 액세스가 최적화되어 널 및 범위 검사가 루프 프롤로그에서만 수행됩니다.
  • 런타임시 동적 패치가있는 가상 호출 사이트 당 하나의 항목 인라인 캐시.
  • mul / div에 대한 리터럴 피연산자에 대한 전력 감소와 같은 틈새 최적화.

Gingerbread에서 getter / setter를위한 간단한 인라인을 추가했습니다. 기본 JIT 프런트 엔드는 여전히 단순한 추적 기반이므로 호출 수신자가 거기에 분기가 있으면 인라인되지 않습니다. 그러나 인라인 캐시 메커니즘은 가상 게터 / 세터가 문제없이 인라인 될 수 있도록 구현됩니다.

우리는 현재 컴파일러가 코드 분석 및 최적화를위한 더 큰 창을 갖도록 단순한 추적을 넘어 컴파일 범위를 확대하기 위해 노력하고 있습니다. 계속 지켜봐주세요.


내 대답이 모든 질문에 대답하지는 않을 것이라고 확신하지만 하나라도 대답하면 승리라고 생각합니다.

당신은 주제에 대한 심오한 지식을 가지고 있고 당신이 원하는 것을 알고있는 것 같습니다. 그래서 당신은 다음을하고 싶을 것입니다. 조사하려는 측면을 포함하는 예제 애플리케이션을 빌드하십시오.

받은 APK를 가져 와서 APK 도구를 통해 실행합니다 . 의도 한대로 수행하기 위해 자신의 코드를 리버스 엔지니어링하는 것은 우리가 알고있는 것처럼 완벽합니다.

APK 도구는 리소스를 추출 및 디코딩하고 .dex파일을 .smali파일로 리버스 엔지니어링 합니다. 파일 을 읽는 방법 과 제한 사항에 대한 자세한 정보를 얻으려면 smali 프로젝트도 검색 할 수 있습니다 .smali.

다시 말씀 드리지만 이것이 귀하의 모든 질문에 대한 답은 아니지만 좋은 시작이 될 것이라고 확신합니다.


먼저, 내가 dalvik에 대한 전문가가 아니며 내 답변 중 일부가 잘못되었을 수 있다고 말하면서 시작하겠습니다. 하지만 저는 dalvik에서 JIT 코드를 파헤 쳤고 dalvik이 실행하는 바이트 코드에 대해 잘 알고 있습니다.

  1. 메소드 인라이닝-내가 아는 한, 이것은 결코 발생하지 않습니다. 나는 그것이 바이트 코드 수준에서는 결코 일어나지 않는다는 것을 거의 긍정적으로 생각한다. 그리고 나는 그것이 미래에있을지라도 현재 JIT 수준에서 일어나지 않는다고 생각한다.

  2. 일반적인 하위 표현식 제거-최종적이지 않은 변수 / 필드를 사용하지 않는 하위 표현식에 대해서만 이것이 수행 될 것이라고 생각합니다. 그때도 그런 일이 일어나더라도 전적으로 긍정적 인 것은 아닙니다. 완료되면 JIT 수준이 아닌 바이트 코드 수준에서 수행 될 것으로 예상합니다.

  3. 배열 조회에 대한 경계 검사-단서 없음

  4. 가치 인라인-내가 아는 한 그렇습니다. 모든 시나리오에서 인라인됩니다.

  5. 분기 예측-확실하지 않음

  6. 간단한 산술-내가 아는 한 멀지 않음

Also, I'd like to mention another avenue of approach to you - dx and dalvik are both open source, so you can dig into them all you like. Although, they're obviously not small codebases, so would take a fair bit of effort to dig into them at that level

참고URL : https://stackoverflow.com/questions/4912695/what-optimizations-can-i-expect-from-dalvik-and-the-android-toolchain

반응형