2010-07-12 5 views
2

내가 읽은 것에서는 Java (보통)가 Java를 컴파일하지 않는 것으로 보입니다. (최적화되지 않았습니다.) 최적화 된 Java 바이트 코드로 최적화되도록 최적화 된 Java 바이트 코드. 사실입니까? 그리고 만약 그것이 있었다면 (아마도 다른 구현에서) 컴파일러를 가져 와서 코드를 최적화 할 수 있었을 것이므로 jit가 할 일이 적습니다 (가능한가요?).가능한 java (또는 기타 메모리 관리 언어) 최적화에 대한 질문

많은 사람들이 Java (및 많은 다른 고급 메모리 관리 언어)의 원시 코드 생성 (때로는 미리 컴파일이라고도 함)에 대해 싫어하는 것으로 나타났습니다. .) 또한 부분적으로는 (적어도 시간 컴파일러가있는 언어의 경우) 컴퓨터 코드에 대한 컴파일이 jit 컴파일러에 의해 수행 될 수있는 최적화를 놓치고 따라서 느려질 수 있다는 생각이 들기 때문에 장기적으로는.

http://en.wikipedia.org/wiki/Profile-guided_optimization (바이너리 컴파일 + 일부 엑스트라를 실행 한 다음 프로그램을 실행하고 테스트 실행의 런타임 정보를 분석하여 실제 사용을 위해 더 최적화 된 바이너리를 생성하려고 시도한 적이 있는지 궁금하게 생각합니다) java/(다른 메모리 관리 언어)와 이것이 jit 코드와 어떻게 비교 될까요? 누구나 단서가 있습니까?

답변

2

프로필 기반 최적화에는 몇 가지주의 사항이 있으며, 그 중 하나는 연결된 Wiki 기사에서도 언급되어 있습니다. 코드가 실제로 사용자 또는 다른 코드에서 사용되는 방식을 나타내는 유효한 샘플은

  • 입니다. 주어진 플랫폼 (CPU, 메모리 + 기타 하드웨어, OS, 기타)에 대한

  • 성능 측면에서 볼 때 일반적으로 (다소간) 동일하다고 간주되는 플랫폼 (예 : Linux에서 실행되는 단일 코어, 이전 Athlon과 512M, 6 코어 Intel과 8G 비교, 그러나 매우 다른 커널 버전이 있음). 주어진 JVM 및 해당 구성에 대한

이러한 변경 사항이 있으면 프로파일 링 결과 (및이를 기반으로하는 최적화)가 더 이상 유효하지 않습니다. 대부분의 최적화는 여전히 유익한 영향을 미치지 만 그 중 일부는 차선책 (또는 성능 저하)이 될 수 있습니다.

언급했듯이 JIT JVM은 프로파일 링과 매우 유사한 기능을 수행하지만 실제로 수행합니다. '핫스팟'이라고도 불리는 이유는 실행 된 코드를 지속적으로 모니터링하고 자주 실행되는 핫 스폿을 찾아 해당 부분 만 최적화하려고하기 때문입니다. 이 시점에서 코드에 대한 더 많은 지식을 활용할 수 있습니다 (코드의 컨텍스트, 다른 클래스에서 사용하는 방법 등) - 사용자와 다른 답변에서 언급했듯이 - 코드로 더 나은 최적화를 수행 할 수 있습니다. 정적 인 것. 모니터링을 계속하고 필요하다면 나중에 최적화의 또 다른 차례를 수행 할 것이며 이번에는 더 많은 비용이 드는 최적화를 찾는 것이 더욱 힘들어집니다.
실생활 데이터 (사용 통계 + 플랫폼 + 구성)를 작업하면 앞에서 언급 한 사항을 피할 수 있습니다.

"프로파일 링"+ JIT-ing에 소요되는 추가 비용이 있습니다. 대부분의 시간은 꽤 잘 보냈다. 당신이주의를 피할 수 있다면

나는 프로파일 유도 최적화는 여전히하지만 일부 특별한 경우, (그것을 이길 짝수 또는) 그와 경쟁 할 수있는 것 같아요 :

  • 당신은 당신의 샘플이 아주 확실하다 실생활 시나리오를 잘 나타내주고 실행 중에 너무 많이 변하지 않을 것입니다.
  • 타겟 플랫폼을 매우 정확하게 알고 프로파일 링을 수행 할 수 있습니다.
  • 물론 JVM과 그 구성을 알고/제어하십시오.

거의 발생하지 않으며 일반적으로 JIT에서 더 나은 결과를 얻을 것이라고 추측하지만 나는 그것에 대한 증거가 없습니다.

JIT 최적화를 수행 할 수없는 JVM을 대상으로하는 경우 프로필 기반 최적화에서 가치를 얻을 수있는 또 다른 가능성 (대부분의 소형 장치에는 이러한 JVM이 있다고 생각합니다).

기타 답변에서 언급 한 단점은 피하는 것이 매우 쉽습니다. 정적/프로필 안내 최적화가 느린 경우 (아마도 경우 일 수 있습니다) 그런 다음 릴리스 (또는 테스터로가는 RC) 또는 야간 빌드 동안 만 수행하십시오 (시간은별로 중요하지 않습니다).
더 큰 문제는 좋은 샘플 테스트 케이스를 갖는 것입니다. 그것들을 생성하고 유지하는 것은 일반적으로 쉽지 않으며 많은 시간이 걸립니다. 특히 자동으로 실행할 수 있도록하려면이 경우 매우 중요합니다.

4

개인적으로 JIT 컴파일과 AOT 컴파일 사이에는 큰 차이가 없지만 클래스 컴파일과 전체 프로그램 최적화 사이에는 차이가 있다고 생각합니다.

javac를 실행하면 단일 .java 파일 만보고 단일 .class 파일로 컴파일됩니다. 모든 인터페이스 구현과 가상 메서드 및 재정의는 유효성을 검사하지만 해결되지 않은 상태로 남아 있습니다 (전체 프로그램을 분석하지 않고 실제 메서드 호출 대상을 알 수 없기 때문에).

JVM은 "런타임로드 및 링크"를 사용하여 모든 클래스를 일관된 프로그램으로 어셈블합니다 (그리고 프로그램의 모든 클래스는 특수 동작을 호출하여 기본로드/연결 동작을 변경할 수 있습니다).

그러나 런타임시 JVM은 거의 모든 가상 메소드를 제거 할 수 있습니다. 그것은 getter와 setter 모두를 인라인하여 원시 필드로 만들 수 있습니다. 그리고 원시 필드가 인라인 될 때 ​​코드를 최적화하기 위해 상수 전파를 수행 할 수 있습니다. 런타임시에는 전용 필드와 같은 것이 없습니다. 그리고 실행중인 스레드가 하나뿐이라면 JVM은 모든 동기화 프리미티브를 제거 할 수 있습니다.

짧게 말하면 전체 프로그램을 분석하지 않으면 불가능한 많은 최적화가 있으며 전체 프로그램 분석을위한 최적의 시간은 런타임에 있습니다.

+0

동의. 일부 AOT 컴파일러 (gcc가 내가 아는 유일한 사람이지만 다른 사람이있을 수도 있음)는이 기능을 가지고 있으며 "링크 타임 최적화"라고 부릅니다. 그것은 비교적 새로운 것이지만, 어떤 기능이 가장 자주 호출 될지 추측하기 위해 여전히 연관되어 있습니다. OP가 언급 한 그 문제에 대한 "프로파일 기반 최적화"가 있긴하지만. – delnan

1

공식 Java 핫 스폿 컴파일러는 런타임에 "적응 형 최적화"를 수행합니다. 이는 본질적으로 언급 한 프로파일 기반 최적화와 동일합니다. 이것은 오랫동안이 자바 구현의 특징이었습니다.

더 많은 정적 분석 또는 최적화를 수행하는 것의 상반 관계는 컴파일 타임에 근본적인 차이가 있습니다. 이는 컴파일러가 실행되는 데 걸리는 시간과 비교하여이 여분의 노력에서 얻을 수있는 수익입니다. MLton과 같은 컴파일러 (Standard ML의 경우)는 정적 검사가 많은 전체 프로그램 최적화 컴파일러입니다. 아주 좋은 코드를 생성하지만, 빠른 시스템에서도 중대형 프로그램에서 매우 느리게됩니다.

그래서 Java 접근법은 JIT와 적응 최적화를 가능한 많이 사용하는 것으로 보입니다. 초기 컴파일 통과는 허용 가능한 유효한 이진을 생성합니다. 절대 반대편은 MLKit과 같은 접근법을 사용하는 것입니다. MLKit은 영역과 메모리 동작에 대한 정적 인 추론을 많이합니다.