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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions