JIT 컴파일된 코드의 성능 분석을 위한 perf/samply 주석 처리 방법

How to annotate JITed code for perf/samply

작성자
HackerNews
발행일
2025년 12월 18일

핵심 요약

  • 1 JIT 컴파일러가 생성한 코드를 Linux perf 및 macOS samply에서 식별할 수 있도록 perf map 인터페이스를 구현하는 방법을 설명합니다.
  • 2 /tmp/perf-{PID}.map 파일에 시작 주소, 크기, 심볼 이름을 기록하는 간단한 형식을 통해 프로파일러가 JIT 프레임 이름을 인식하게 합니다.
  • 3 YJIT 및 ZJIT은 이 인터페이스를 지원하며, I/O 오버헤드를 고려하여 전용 플래그를 통해 선택적으로 활성화하는 방식을 채택합니다.

도입

JIT(Just-In-Time) 컴파일러는 런타임에 동적으로 기계어를 생성하기 때문에, 표준 시스템 프로파일러가 실행 중인 함수의 이름을 파악하기 어렵다는 문제가 있습니다. 본 글은 Ruby의 YJIT이나 저자의 ZJIT 프로젝트에서 Linux의 perf 및 macOS의 samply 도구가 JIT된 코드의 스택 프레임을 정확히 표시할 수 있게 돕는 perf map 인터페이스의 구현 원리와 방법을 다룹니다.

perf map 인터페이스의 핵심 원리

  • 파일 경로 및 형식: 프로파일러는 /tmp/perf-{PID}.map 경로에 위치한 파일을 참조합니다. 여기서 PID는 프로세스 ID를 의미합니다.

  • 데이터 레코드: 각 줄은 START SIZE symbolname 형식을 따릅니다.

    • START: 함수의 시작 메모리 주소 (0x 접두사 없는 16진수)
    • SIZE: 코드의 크기 (16진수)
    • symbolname: 해당 코드 영역에 부여할 함수 또는 심볼의 이름

ZJIT의 구현 사례

ZJIT은 Rust 언어를 사용하여 다음과 같이 구현되었습니다:

  • 파일 오픈: std::fs::OpenOptions를 통해 파일을 생성하거나 기존 파일에 내용을 추가(append)할 수 있도록 설정합니다.

  • 정보 기록: 함수가 생성될 때마다 해당 함수의 메모리 범위와 이름을 writeln!을 통해 파일에 기록합니다.

  • 성능 고려: 매번 발생하는 파일 I/O는 성능에 영향을 줄 수 있으므로, --zjit-perf와 같은 명령행 인자를 사용해 프로파일링이 필요할 때만 기능을 켜도록 설계합니다.

활용 가능한 도구 및 대안

  • samply: macOS와 Linux 모두에서 사용 가능한 강력한 프로파일러로, perf map 인터페이스를 완벽히 지원합니다.

  • perf record: Linux 시스템의 표준 도구로, JIT된 프레임의 이름을 결과물에 포함할 수 있게 됩니다.

  • JIT dump: perf map보다 나중에 등장한 방식으로, 더 복잡한 정보를 담을 수 있는 jitdump 파일을 생성한 후 perf inject를 사용하는 대안적 인터페이스도 존재합니다.

결론

JIT 컴파일러 개발에 있어 perf map 지원은 디버깅과 성능 최적화의 필수 요소입니다. 간단한 텍스트 기반 인터페이스를 구현함으로써 복잡한 프로파일링 도구와의 호환성을 즉각적으로 확보할 수 있으며, 이는 YJIT과 같은 Ruby의 고성능 엔진 개발 과정에서도 매우 유용하게 활용되는 기술적 장치입니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!