programing

Java에서 올바른 마이크로벤치마크를 작성하려면 어떻게 해야 하나요?

randomtip 2022. 7. 21. 22:08
반응형

Java에서 올바른 마이크로벤치마크를 작성하려면 어떻게 해야 하나요?

Java에서 올바른 마이크로벤치마크를 작성(실행)하려면 어떻게 해야 합니까?

코드 샘플과 여러 가지 생각할 점을 나타내는 코멘트를 찾고 있습니다.

예:벤치마크는 시간/반복 또는 반복/시간을 측정해야 하며 그 이유는 무엇입니까?

관련:스톱워치 벤치마킹이 허용되나요?

Java HotSpot 작성자의 마이크로 벤치마크 작성 힌트:

규칙 0: JVM 및 마이크로벤치마킹에 대한 평판이 좋은 문서를 읽어보십시오.Brian Goetz, 2005년.micro-benchmark에 너무 많은 것을 기대하지 마십시오.micro-benchmark는 제한된 범위의 JVM 성능 특성만 측정합니다.

규칙 1: 항상 테스트 커널을 끝까지 실행하는 웜업 단계를 포함합니다.타이밍 단계 전에 모든 초기화 및 컴파일을 트리거할 수 있습니다.(워밍업 단계에서는 몇 번 반복해도 문제가 없습니다.경험적으로 볼 때 내부 루프의 반복 횟수는 수만 번입니다.)

규칙 2: 항상 다음을 사용하여 실행-XX:+PrintCompilation,-verbose:gc컴파일러 및 JVM의 다른 부분이 타이밍 단계에서 예기치 않은 작업을 하지 않는지 확인할 수 있습니다.

규칙 2.1: 타이밍 단계 및 워밍업 단계의 시작 및 종료 시 메시지를 인쇄하여 타이밍 단계 중에 규칙 2에서 출력이 없는지 확인할 수 있습니다.

규칙 3: 다음 두 가지 차이점에 유의하십시오.-client ★★★★★★★★★★★★★★★★★」-serverOSR の os os os 。-XX:+PrintCompilation포인트를 하여 OSR 를 들어 flag " " " " " " " " " " " at-sign " " " OSR " " " 。하다Trouble$1::run @ 2 (41 bytes)최고의 퍼포먼스를 원한다면 클라이언트보다 서버를, OSR보다 일반 서버를 선호합니다.

규칙 4: 초기화 효과에 유의하십시오.인쇄가 클래스를 로드 및 초기화하므로 타이밍 단계 중에는 처음 인쇄하지 마십시오.클래스 로드를 특별히 테스트하지 않는 한(이 경우 테스트클래스만 로드하는 경우) 워밍업 단계(또는 최종 보고서 단계) 이외에는 새 클래스를 로드하지 마십시오.규칙 2는 그러한 효과에 대한 당신의 첫 번째 방어선이다.

규칙 5: 최적화 해제 및 재컴파일 효과에 유의하십시오.타이밍 국면에서 처음으로 코드 패스를 사용하지 마십시오.컴파일러는 패스가 전혀 사용되지 않는다는 이전의 낙관적인 가정에 근거해 코드를 정크 해 재컴파일 할 가능성이 있습니다.규칙 2는 그러한 효과에 대한 당신의 첫 번째 방어선이다.

규칙 6: 적절한 도구를 사용하여 컴파일러의 생각을 읽고 컴파일러가 생성하는 코드에 깜짝 놀랄 것으로 예상합니다.무엇이 더 빠르거나 느린지에 대한 이론을 형성하기 전에 코드를 직접 검사하십시오.

규칙 7: 측정 시 노이즈를 줄입니다.조용한 기계에서 벤치마크를 실행하고 여러 번 실행하여 특이치를 삭제합니다.사용하다-Xbatch하십시오.-XX:CICompilerCount=1컴파일러와 병렬로 동작하지 않도록 합니다.오버헤드를 GC를 설정합니다.Xmx) 등가Xms사용할 수 있는 경우 사용합니다.

규칙 8: 벤치마크에 라이브러리를 사용합니다.아마 더 효율적이며 이미 이 목적으로 디버깅되어 있을 것입니다.JMH, Caliper 또는 Bill, Paul의 Java용 우수한 UCSD 벤치마크 등.

이 질문에 답변으로 표시되어 있는 것은 알고 있습니다만, 마이크로 벤치마크를 작성하는 데 도움이 되는2개의 라이브러리를 언급하고 싶습니다.

Google 캘리퍼

시작하기 자습서

  1. http://codingjunkie.net/micro-benchmarking-with-caliper/
  2. http://vertexlabs.co.uk/blog/caliper

오픈으로부터의 JMHJDK

시작하기 자습서

  1. JVM에 대한 벤치마크 함정 방지
  2. Java Microbenchmarking에 JMH 사용
  3. JMH의 개요

Java 벤치마크에서 중요한 것은 다음과 같습니다.

  • 타이밍을 맞추기 전에 코드를 여러 번 실행하여 먼저 JIT를 예열합니다.
  • 몇 초 또는 (더 나은) 수십 초 만에 결과를 측정할 수 있을 만큼 충분히 오래 실행했는지 확인하십시오.
  • 할 수 동안System.gc()할 수 있는 "할 수 "깨끗한" 메모리 공간을 확보할 수 있습니다).gc()보증이라기보다 힌트에 가깝지만, 제 경험상 쓰레기가 수거될 가능성이 매우 높습니다.)
  • 나는 반복과 시간, 그리고 "최고의" 알고리즘이 1.0의 점수를 받고 다른 알고리즘이 상대적인 방식으로 점수를 얻도록 스케일링할 수 있는 시간/반복 점수를 표시하는 것을 좋아한다.즉, 모든 알고리즘을 오랜 시간 동안 실행할 수 있으며 반복 횟수와 시간은 다양하지만 동일한 결과를 얻을 수 있습니다.

에서의 벤치마킹 프레임워크 설계에 대해 블로그를 작성 중입니다.NET. 당신에게 아이디어를 줄 수 있는 이전 게시물이 몇 개 있습니다. 물론 모든 것이 적절한 것은 아니지만, 일부일 수도 있습니다.

jmh는 OpenJDK에 최근에 추가된 것으로 Oracle의 일부 성능 엔지니어에 의해 작성되었습니다.볼만 하군

jmh는 Java 및 JVM을 대상으로 하는 다른 언어로 작성된 nano/micro/macro 벤치마크를 구축, 실행 및 분석하기 위한 Java 하니스입니다.

샘플 테스트 코멘트에는 매우 흥미로운 정보가 포함되어 있습니다.

다음 항목도 참조하십시오.

벤치마크는 시간/반복 또는 반복/시간을 측정해야 하며 그 이유는 무엇입니까?

테스트하려는 항목에 따라 다릅니다.

지연 시간에 관심이 있는 경우 시간/반복을 사용하고 처리량에 관심이 있는 경우 반복/시간을 사용합니다.

벤치마크된 코드로 계산된 결과를 사용해야 합니다.그렇지 않으면 코드가 최적화되어 없어질 수 있습니다.

두 알고리즘을 비교하려는 경우 순서를 번갈아 가면서 각각에 대해 최소 2개의 벤치마크를 수행합니다.

for(i=1..n)
  alg1();
for(i=1..n)
  alg2();
for(i=1..n)
  alg2();
for(i=1..n)
  alg1();

같은 알고리즘의 런타임에서 몇 가지 현저한 차이(가끔 5~10%)를 다른 경로로 발견했다.

또한 각 루프의 실행 시간이 최소 10초 이상이 되도록 n이 매우 큰 것을 확인합니다.반복 횟수가 많을수록 벤치마크 시간의 중요도가 높아지고 데이터의 신뢰성이 높아집니다.

Java에서 micro-benchmark를 작성할 때는 많은 함정이 있을 수 있습니다.

첫 번째: 가비지 수집, 캐싱 효과(파일용 OS, 메모리용 CPU), IO 등 랜덤으로 시간이 걸리는 모든 종류의 이벤트를 사용하여 계산해야 합니다.

둘째: 매우 짧은 간격 동안 측정된 시간의 정확성을 신뢰할 수 없습니다.

셋째: JVM은 실행 중에 코드를 최적화합니다.따라서 동일한 JVM에서 서로 다른 실행 속도가 점점 빨라집니다.

권장사항: 벤치마크를 몇 초간 실행할 수 있습니다.이것은 밀리초 이상의 런타임보다 신뢰성이 높아집니다.JVM을 예열합니다(JVM이 최적화를 실행할 수 있도록 측정하지 않고 벤치마크를 한 번 이상 실행).벤치마크를 여러 번(약 5회) 실행하고 중위수 값을 취합니다.새로운 JVM 인스턴스(벤치마크의 새로운 Java마다 호출)에서 모든 마이크로벤치를 실행합니다.그렇지 않으면 JVM의 최적화 효과가 나중에 실행되는 테스트에 영향을 줄 수 있습니다.워밍업 단계에서 실행되지 않은 작업은 실행하지 마십시오(클래스 로드 및 재컴파일이 트리거될 수 있음).

또한 다른 구현을 비교할 때 마이크로 벤치마크의 결과를 분석하는 것도 중요할 수 있습니다.따라서 유의성 검사를 실시해야 합니다.

이는 구현이A벤치마크 실행의 대부분이 구현보다 빠를 수 있습니다.B.그렇지만A또한 분산이 더 높을 수 있으므로 측정된 퍼포먼스 이점은 다음과 같습니다.A비교해도 별로 중요하지 않다B.

따라서 마이크로 벤치마크를 올바르게 작성하고 실행하는 것뿐만 아니라 올바르게 분석하는 것도 중요합니다.

다른 훌륭한 조언에 덧붙여, 다음 사항에도 유의합니다.

일부 CPU(TurboBoost 탑재 인텔 Core i5 범위 등)에서는 온도(및 현재 사용되는 코어의 수 및 사용률)가 클럭 속도에 영향을 줍니다.CPU는 동적으로 클럭되기 때문에 결과에 영향을 줄 수 있습니다.예를 들어 단일 스레드 응용 프로그램을 사용하는 경우 모든 코어를 사용하는 응용 프로그램보다 최대 클럭 속도(TurboBoost 사용)가 더 높습니다.따라서 일부 시스템에서 싱글 스레드와 멀티 스레드 성능을 비교하는 데 방해가 될 수 있습니다.온도와 부피는 터보 주파수가 유지되는 기간에도 영향을 미칩니다.

직접 제어할 수 있는 보다 근본적으로 중요한 측면: 올바른 것을 측정하고 있는지 확인하십시오.예를 들면,System.nanoTime()특정 코드를 벤치마킹하려면 관심 없는 것을 측정하지 않도록 적절한 위치에 콜을 할당합니다.예를 들어, 다음 작업을 수행하지 마십시오.

long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");

문제는 코드가 끝났을 때 즉시 종료 시간을 알 수 없다는 것입니다.대신 다음을 시도해 보십시오.

final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");

http://opt.sourceforge.net/ Java Micro Benchmark - 다양한 플랫폼에서 컴퓨터 시스템의 비교 성능 특성을 판단하기 위해 필요한 제어 태스크입니다.최적화 결정을 안내하고 다양한 Java 구현을 비교하는 데 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java

반응형