-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
느낀점
- 통계 너무 어렵다
정리
- 벤치마킹은 최대한 공정하게 하는 것
- 최대한 시스템의 가변적인 부분은 테스트 간에 불변성을 유지해야함 (변인통제)
- 자바 런타임이 코드를 최적화하기 위해 많은 것을 함
- 그러므로 최적화가 미치는 영향을 구체적으로 이해하고 완전히 이해하고 설명하기란 불가능
벤치마킹 팁
- 실제 운영환경에서와 동일하게 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에는 이 모델이 잘 맞지 않음
허위 상관
- 상관관계가 있다고 인과관계를 나타내는 것은 아님
- 관련된 만화도 있어요ㅎㅎ https://yozm.wishket.com/magazine/detail/1913/
- 아무 관계도 없는 측정값을 보면 연관성이 전혀 없는 경우가 있지만 밀접한 상관관계가 있는 것처럼 보임
- ex) 아케이드 게임 총 매출액 대비 미국 컴퓨터 과학 박사 인원수의 상관관계
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels