Skip to content

Chapter 05. 마이크로벤치마킹과 통계 #5

@MinJunKweon

Description

@MinJunKweon

느낀점

  • 통계 너무 어렵다

정리

  • 벤치마킹은 최대한 공정하게 하는 것
  • 최대한 시스템의 가변적인 부분은 테스트 간에 불변성을 유지해야함 (변인통제)
  • 자바 런타임이 코드를 최적화하기 위해 많은 것을 함
  • 그러므로 최적화가 미치는 영향을 구체적으로 이해하고 완전히 이해하고 설명하기란 불가능

벤치마킹 팁

  • 실제 운영환경에서와 동일하게 JIT 컴파일러가 이미 최적화된 상태에서 테스트를 하기 위해 Warm-Up 후 테스트하는 것이 좋음
  • GC는 사용자가 조절이 불가능하기 때문에 최대한 GC가 일어나지 않는 부분에서만 캡처를 진행하게 해야함
  • 테스트하려는 코드를 자동 최적화해서 벤치마크 하려던 부분이 최적화될 위험이 있음
  • 오차 범위를 구해서 수집한 값의 신뢰도를 파악하는 게 좋음
  • 멀티스레드 코드 벤치마크는 매우 어려움. 하드웨어 경합이 발생할 수도 있음
  • 시스템 전체를 벤치마크하는 방법도 있음. 작은 수준의 오차는 무시함
  • 공통 프레임워크를 이용해 처리함하는 방법도 있음. JMH가 그런 툴

JVM 옵션 팁

  • -Xms2048m -Xmx2048m : 최소/최대 힙 크기 조정하는 옵션 (메모리 옵션)
  • -XX:+PrintComilation : 메서드를 컴파일할 때마다(컴파일 이벤트가 발생할 때마다) 로깅하는 옵션
  • -verbose:gc : 가비지 컬렉션 로깅

마이크로벤치마킹

  • 내가 짠 코드 이외의 원인으로 성능이 저하되었을 수 있다. (인프라 문제)
  • 이 경우 마이크로벤치마킹은 알아차리기 어려운 문제가 있다.
  • 마이크로 벤치마킹을 해야하는 경우
    • 공통 범용 라이브러리를 개발할 때
    • OpenJDK 또는 다른 자바 플랫폼 구현체를 개발할 때
    • 지연에 극도로 민감한 코드를 개발할 때

자바 마이크로벤치마킹 툴 - JMH

  • 위에서 언급한 마이크로 벤치마크
  • 벤치마크 프레임워크가 반복을 여러번하면 루프 최적화를 수행할 수 있음
  • JMH는 루프 최적화에 걸리지 않도록 반복횟수를 설정해서 루프 안에 감싸넣는 방식으로 동작함

JMH의 BlackHole

  • 메소드 내에서 실행된 코드가 사이드 이펙트를 전혀 일으키지 않고 그 결과를 사용하지 않을 경우 해당 메서드를 삭제 대상으로 삼음
  • 벤치마크 메소드가 반환한 단일 결과값을 암묵적으로 블랙홀에 할당함
  • 블랙홀은 4가지 장치를 이용해 최적화를 못하게 보호함
    • 런타임에 죽은 코드를 제거하는 최적화를 못하게함
    • 반복되는 계산을 상수 폴딩하지 않게 만듦
    • 값을 읽거나 쓰는 행위가 캐시 라인에 영향을 끼치는 잘못된 공유 현상 방지
    • 쓰기 장벽으로부터 보호함

쓰기 장벽(Write Wall)

  • 쓰기 리소스가 포화되어서 사실상 애플리케이션에 병목을 초래하는 지점
  • 쓰기 장벽에 이르면 캐시에 영향을 미치고 쓰기 전용 버퍼가 오염될 수 있음

블랙홀 구현

public volatile int i1 = 1, i2 = 2;

public final void consume(int i) {
	if (i == i1 & i == i2) {
		// SHOULD NEVER HAPPEN
		nullBait.i1 = i; // implicit null pointer exception
  }
}

이 코드에 숨겨진 트릭은 다음과 같음:

  • i1, i2가 volatile이기 때문에 반드시 런타임에 evaluation 되어야함
  • if 문은 절대 true가 될 일은 없지만 컴파일러는 이 코드를 실행시켜야함
  • if 문에 비트 연산자 AND가 있어서 추가 분기 로직이 문제될 일 없고 일정한 성능이 보장됨
public int tlr = (int) System.nanoTime();

public final void consume(Object obj) {
	int tlr = (this.tlr = (this.tlr * 1664525 + 1013904223));
	if (tlr & tlrMask) == 0) {
		// SHOULD ALMOST NEVER HAPPEN IN MEASUREMENT
		this.obj1 = obj;
		this.tlrMask = (this.tlrMask << 1) + 1;
	}
}
  • 컴파일러가 탈출분석(Escape analysis)를 해보고 이 객체가 어느 객체와도 동등할 수 없다고 결론 내리면 비교문 자체가 retrun false로 최적화 될 수 있음
  • 객체가 아주 드문 경우에만 실행된다는 조건하에 소비되도록 함
    • 그래서 객체를 할당하지 않아도 소비될 수 있게 만드는 것
  • 고도로 정확한 마이크로벤치마킹 툴을 개발하면서 클래스 문서화도 잘해놓았음

JMH의 강력한 기능

  • 컴파일러를 제어함
  • 벤치마크 도중 CPU 사용 수준을 시뮬레이션 함
    • 실제 CPU 사이클을 소모해 다양한 CPU 부하 상황에서 벤치마크 시뮬레이션 가능

JVM 성능 통계

  • 정확도(Accuracy) : 원인을 알 수 없는 요인이 상관관계 있는 형태로 측정되는 정도 (계통 오차)
  • 정밀도(Precision) : 어떤 상관관계 없이 결과에 영향을 끼치는 오차가 얼마나 높은지 정도 (랜덤 오차)

계통 오차

  • 백엔드 웹 서비스의 성능 테스트를 수행한다고 가정했을 때, 모든 요청이 전체적으로 느린 경우
  • ex) 테스트 대상 서버는 영국이지만, 부하 테스트는 인도 뭄바이에서 한다면 이럴 수 있음
  • 계통 효과가 커서 실제 응답 시간의 차이가 묻혀버림
  • 테스트 설정이 잘못돼서 발생한 것이므로 환경을 다시 맞추고 수행하면 오차는 없어짐

랜덤 오차

  • 원인을 알 수 없는 경우가 있음
  • 대부분 정규 분포(가우시안 분포)를 따름
  • 오차가 측정값에 미치는 긍정적/부정적 영향도가 얼추 비슷한 경우에는 적합하지만 JVM에는 이 모델이 잘 맞지 않음

허위 상관

  • 상관관계가 있다고 인과관계를 나타내는 것은 아님
  • 아무 관계도 없는 측정값을 보면 연관성이 전혀 없는 경우가 있지만 밀접한 상관관계가 있는 것처럼 보임
  • ex) 아케이드 게임 총 매출액 대비 미국 컴퓨터 과학 박사 인원수의 상관관계

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions