처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.04.27 21

리눅스에서 시간을 가장 빠르게 읽는 법, vDSO를 파헤치다

Hacker News 원문 보기
리눅스에서 시간을 가장 빠르게 읽는 법, vDSO를 파헤치다

시간 한 번 읽는 데 얼마나 걸릴까

프로그램에서 "지금 몇 시야?"를 묻는 건 너무 흔한 일이라 비용을 거의 안 따져요. 그런데 고성능 거래 시스템, 트레이싱 라이브러리, 데이터베이스 같은 데서는 1초에 수백만 번씩 시간을 읽거든요. 이때는 한 번 호출에 50나노초냐 5나노초냐가 전체 처리량을 좌우합니다. hmpcabral 블로그의 이 글은 "리눅스에서 가장 빠른 타임스탬프 얻는 법"을 다양한 방법으로 벤치마크하면서 vDSO, TSC, RDTSC 같은 개념을 차근차근 풀어놔요. 시간 함수 호출 비용을 한 번도 의식해본 적 없는 분들에게 특히 재밌는 글이에요.

일반 시스템 콜은 왜 느린가

예전에는 시간을 알려면 gettimeofday(2) 같은 시스템 콜을 호출했어요. 시스템 콜이 뭐냐면, 사용자 프로그램이 커널(운영체제 핵심부)에게 일을 시키려고 권한을 잠깐 넘기는 동작이에요. 이게 비싸요. CPU가 사용자 모드에서 커널 모드로 전환하면서 레지스터를 저장하고, 권한 검사하고, 커널 코드로 점프하고, 다시 돌아옵니다. 이 왕복만 보통 수백 나노초가 들어요. 시간 한 번 읽자고 그 비용을 내는 건 너무 비싸죠.

그래서 리눅스는 vDSO(virtual Dynamic Shared Object)라는 영리한 트릭을 만들었어요. 이게 뭐냐면, 커널이 "시간 같은 자주 묻는 정보"를 사용자 프로세스의 주소 공간에 매핑된 작은 공유 라이브러리에 미리 넣어두는 거예요. 그러면 clock_gettime(CLOCK_MONOTONIC, &ts) 같은 호출이 시스템 콜로 가지 않고, 그 매핑된 메모리에서 직접 값을 읽어 옵니다. 모드 전환이 없으니 비용이 1/10 수준으로 줄어요. 글쓴이의 측정에서는 vDSO 경유가 보통 20~30 나노초 수준으로 나옵니다.

TSC를 직접 읽으면 더 빠를까

글의 진짜 재밌는 부분은 그다음이에요. x86 CPU에는 TSC(Time Stamp Counter)라는 레지스터가 있어요. CPU 클록 사이클을 매번 1씩 올리는 카운터인데, RDTSC 명령어 한 번이면 읽을 수 있어요. 이건 시스템 콜도 아니고 vDSO 매핑 조회도 아닙니다. 그냥 CPU 명령어 하나죠. 측정해 보면 5~7 나노초 정도로, vDSO보다 또 4~5배 빨라요.

그런데 이걸 그냥 쓸 수는 없어요. 몇 가지 함정이 있거든요. 첫째, CPU 코어마다 TSC가 다를 수 있어요. 스레드가 코어 사이를 옮겨다니면 시간이 거꾸로 가는 것처럼 보일 수 있죠. 다행히 요즘 x86은 "invariant TSC"를 지원해서 코어 간 동기화가 보장되긴 하지만, 가상 머신이나 오래된 하드웨어에서는 여전히 위험합니다. 둘째, TSC는 사이클 단위지 나노초가 아니에요. 실제 시간으로 환산하려면 CPU 주파수를 알아야 하고, 주파수 스케일링이 켜져 있으면 비율이 들쭉날쭉해요. invariant TSC는 다행히 항상 일정한 비율로 증가하도록 설계됐지만, 그 비율을 얻으려면 한 번은 calibration이 필요합니다.

셋째, RDTSC명령어 재배치(out-of-order execution) 때문에 정확히 그 시점을 측정하지 못할 수 있어요. 그래서 정밀한 측정에는 RDTSCPLFENCE; RDTSC 같이 직렬화 명령어를 끼워 넣습니다. 그러면 안정적이지만 약간 더 느려져요.

그래서 뭘 써야 하나

글쓴이는 결국 이렇게 정리해요. 일반 애플리케이션 코드라면 clock_gettime(CLOCK_MONOTONIC_COARSE)가 정답에 가까워요. CLOCK_MONOTONIC보다 정밀도는 떨어지지만(보통 4ms 단위) vDSO조차 거치지 않고 단순히 커널이 주기적으로 갱신하는 메모리 값을 읽어와서 5나노초 안쪽으로 끝납니다. 로깅이나 타임아웃 체크처럼 ms 정밀도면 충분한 곳에서는 이게 압도적으로 효율적이에요.

나노초 정밀도가 필요하면 일반 CLOCK_MONOTONIC(vDSO)을 쓰고, 정말 핫 패스에서 사이클 단위 측정이 필요할 때만 RDTSC를 직접 쓰라는 거예요. 그리고 RDTSC를 쓸 거면 코어 핀닝(thread pinning), invariant TSC 확인, calibration 같은 작업이 함께 따라와야 합니다.

한국 개발자에게 주는 시사점

실무 백엔드 개발자가 매일 만질 일은 많지 않아요. 그런데 한 가지 직접 겪을 만한 사례가 있는데, 로깅 라이브러리의 시간 호출 비용이에요. 초당 10만 건 이상 로그를 찍는 서비스에서, 매 로그마다 clock_gettime을 부르면 그것만으로 CPU의 1~2%를 갉아먹기도 하거든요. 이때 COARSE 시계로 바꾸거나, 시간을 한 번 읽어 캐싱하고 N건 단위로 갱신하는 패턴이 큰 차이를 만듭니다.

APM 도구나 분산 트레이싱(OpenTelemetry, Pinpoint 등)을 만들거나 튜닝하시는 분에게는 핵심 지식이에요. 트레이스의 span 시작/끝마다 시간 호출이 들어가니까요. 또 게임 서버나 실시간 매칭 시스템에서 마이크로초 단위 측정이 필요한 분들도 RDTSC 패턴을 한 번쯤 학습해 둘 가치가 있어요.

마무리

시간을 읽는 일조차 사실은 "커널을 거치냐, vDSO를 거치냐, CPU 명령어 하나로 끝내냐"라는 깊은 선택이 숨어 있다는 게 운영체제와 하드웨어의 재미있는 지점이에요. 여러분 코드의 핫 루프에서 시간을 어떤 방식으로 읽고 있는지, 한 번도 의식해본 적 없으셨다면 오늘 한 번 straceperf로 들여다보시는 건 어떨까요?


🔗 출처: Hacker News

이 뉴스가 유용했나요?

TTJ 코딩클래스 정규반

월급 외 수입,
코딩으로 만들 수 있습니다

17가지 수익 모델을 직접 실습하고, 1,300만원 상당의 자동화 도구와 소스코드를 받아가세요.

144+실전 강의
17개수익 모델
4.9수강생 평점
정규반 자세히 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.