18P by GN⁺ 3일전 | ★ favorite | 댓글 2개
  • 일반적으로 서버 성능 한계는 top 같은 모니터링 도구의 % CPU 사용률로 판단하지만, 실제로는 이 지표가 선형적으로 성능을 반영하지 않음
  • Ryzen 9 5900X 환경에서 stress-ng로 테스트한 결과, 50% 사용률일 때 실제 작업량은 60~100% 에 달해 지표와 큰 괴리가 있음
  • 주요 원인은 하이퍼스레딩터보 부스트로, 논리 코어 간 자원 공유와 클럭 속도 변화가 지표를 왜곡함
  • 따라서 단순한 CPU 사용률 대신, 실제 처리 가능한 작업량 벤치마크와 현재 처리량 비교가 더 정확한 지표임
  • CPU 사용률을 선형적으로 해석하면 성능 추정에 큰 오류가 발생하므로, 시스템 계획 시 벤치마크 기반 접근이 필요함

서버의 CPU 사용률 수치와 실제 처리량의 불일치

  • 서버 운영 시, 많은 사람이 최대 사용률에 가까운지 확인하고 싶어함
  • 일반적으로 top 등의 모니터링 도구를 통해 네트워크, 메모리, CPU 사용률 중 가장 높은 값을 참조함
  • 하지만 실제로 CPU 사용률 수치와 처리 가능한 작업량이 선형적으로 증가하지 않는 문제가 발생

테스트 환경 및 방법

  • Ubuntu 데스크톱 + Ryzen 9 5900X (12코어/24스레드) 기반 실험
  • Precision Boost Overdrive(Turbo) 활성화
  • stress-ng로 다양한 부하(1~24 워커, 1~100% 사용률) 시뮬레이션
  • 측정 지표: 시스템이 보고하는 CPU 사용률과 실제 연산량(Bogo ops)

결과 요약

  • 일반 CPU 부하: 50% 사용률 시 실제 60~65% 처리량
  • 64비트 정수 연산: 50% 사용률 시 65~85% 처리량
  • 행렬 연산(Matrix math): 50% 사용률 시 80~100% 처리량
    • 실제로는 추가 워커가 성능에 기여하지 않아도 CPU 사용률은 상승함

원인 분석

  • 하이퍼스레딩

    • 12개 물리 코어 + 12개 논리 코어 구조
    • 12개 이하 워커는 물리 코어에 최적 배치되지만, 초과 시 논리 코어 공유로 성능 저하
    • 특히 SIMD 연산(행렬 연산) 에서는 공유 자원이 없어 성능 향상 불가
  • 터보 부스트

    • 저부하 시 4.9GHz → 풀로드 시 4.3GHz로 15% 클럭 저하
    • CPU 사용률 계산식(= busy cycles / total cycles)에 왜곡 발생
      • 분모(총 사이클 수)가 줄어들면서, 사용률 상승 폭이 실제 작업량보다 과대평가됨

시사점

  • CPU 사용률은 절대적 성능 지표가 아님
  • 서버 용량 산정 및 성능 예측 시:
    • 1. 벤치마크로 최대 처리량 측정
    • 2. 실시간 처리량 모니터링
    • 3. 두 값을 비교하여 성능 한계 근접 여부 판단
  • CPU 아키텍처(AMD vs Intel), 하이퍼스레딩 효율, 터보 동작 방식에 따라 편차가 크므로 프로세서별 분석 필요

결론

  • CPU 사용률은 단순히 바쁜 사이클 비율일 뿐, 실제 처리 성능을 정확히 반영하지 않음
  • 효율적 활용 시 "50% 사용률"이라도 이미 최대 성능의 80~100% 수준일 수 있음
  • 따라서 성능 모니터링과 시스템 계획은 CPU 사용률 대신 벤치마크 기반 작업 처리량을 중심으로 해야 함
Hacker News 의견
  • CPU utilization은 명확하게 정의된 양을 측정하는 것임에 거짓이 아니라고 생각함, 하지만 사람들이 용량 모델을 만들려고 이것을 외삽할 때 실제와 기대가 어긋남을 경험함
    Hyperthreading(SMT)와 Turbo(클럭 스케일링)은 비선형성을 유발하는 여러 변수 중 일부에 불과하며, 코어 간에 공유되는 메모리 대역폭, 인터커넥트 용량, 프로세서 캐시 등도 부하가 증가할수록 ‘고갈’되는 자원임
    소프트웨어상에서도, 예를 들어 spinlock 같은 현상은 utilization에 비선형 영향을 끼칠 수 있음
    대다수 CPU utilization 지표는 수 초 ~ 1분 단위로 긴 평균을 내는데, 레이턴시 민감 서버의 성능에 중요한 일들은 수십~수백 밀리초 내에 발생함
    그래서 멀티초 평균의 utilization은 burst 패턴과 부드러운 패턴을 구별하지 못함
    하지만 제안한 방식, 즉 "오류나 허용 불가능한 레이턴시가 발생하기 전까지 서버가 얼마나 많은 작업을 할 수 있는지 벤치마크"하는 접근도 본질적으로 불안정함
    서버가 불안정해지기 시작하는 지점을 찾으려 할 때 측정값이 매우 noisy해지고, 큐잉 이론 상에서도 임계점 근처에선 모든 노이즈가 증폭됨
    또한 “서버가 지금 하고 있는 작업량” 자체도 흔히 불안정하게 정의됨 (RPS인가? 요청마다 비용이 다르고, IPC도 시간대마다 달라짐)
    결국 부하테스트 접근법에서 나오는 신뢰구간도, 이용률 지표로 경험적 모델을 만드는 것과 대동소이한 수준임. 전제는 utilization을 올바르게 측정하는 것임

    • 만약에 자신이 perf나 ftrace를 쓸 줄 안다면, 단기간에 매우 상세한 프로세서 메트릭을 얻어서 cache miss나 memory access로 인한 CPU stall, 스케줄러 영향 등 다양한 원인을 직접 볼 수 있음
      그런데 대부분 사람들은 IPC, 캐시 히트율 같은 지표를 받아들여도 그걸로 뭘 해야 할지 모름
      결국 대부분 사람들이 진짜 관심 있는 건 레이턴시와 utilization임
      거칠게 이야기하면, 대다수 워크로드에서는 CPU utilization이 80%를 넘기 전까지는 레이턴시에 별 문제 없음
      하지만 그 이상의 utilization에서는 워크로드 레이턴시에 심각한 영향을 끼치기 시작함
      얼마나 레이턴시에 영향이 있는지는 각자의 워크로드를 직접 재봐야 알 수 있음
      레이턴시에 얼마나 민감하냐도 조직과 목적에 따라 다르고, 간혹은 throughput 최적화가 더 중요할 수도 있음
      레이턴시와 throughput을 둘 다 신경 쓴다면 둘 다 측정하고, 적절한 트레이드오프를 직접 결정해야 함

    • "작업량"의 정의 자체가 흔들리는 것이 핵심 포인트 중 하나라고 생각함
      예를 들면 public-facing 서비스에서 실사용자 요청을 다루는 것인지, 아니면 백엔드에서 쌓아둔 데이터를 차분히 계산하는 AI 학습용 워크로드인지도 다르다고 봄
      내 방식은, 버스트가 종종 발생할 수밖에 없는 현대 멀티코어 하이퍼스레드 CPU 환경에서는, CPU utilization이 60%면 이미 ‘부하가 높은’ 서버로 간주함
      만약 하루 중 상당한 시간 동안 60% 이상이라면 작업을 나누는 것이 적절하다고 여김 (주로 유저 요청에 대응하는 서비스 기준임)
      과거엔 이런 기준이 클라우드 오토스케일을 흔히 고민하게 만들었음
      요즘은 100코어 넘는 서버도 3만불 내외면 써볼 수 있어서 상황이 더 복잡해짐
      요즘이라면, 실서버 하드웨어를 다소 과다하게 프로비저닝하고, 필요에 따라 클라우드 서비스 (혹은 Kubernetes 기반 내부 클라우드)로 확장하는 Hybrid 방식을 지향하겠음
      StackOverflow가 초기 시절에 전용 랙과 10Gbps 업링크로 엄청난 트래픽을 효율적으로 운영했고, 지금은 그보다 더 쉽게 이런 운영이 가능함
      결론적으로, 내 기준은 CPU load가 65%를 30분 이상 유지하면 이미 100% 효과적 사용으로 인정하고, 빠른 시일 내에 확장이 필요하다고 판단함

    • 최신 학회 IEEE Hot Interconnects 키노트에서 Ultra Ethernet의 레이턴시 튜닝 사례도 언급됨
      2초, 5초 단위로는 평탄해 보여도 100ms 스케일로 들여다보면 frame burst 현상이 명확하게 드러남
      즉, 프로파일링의 측정 윈도우가 실제 워크로드와 안 맞으면 false negative로 잘못된 판단을 내릴 수 있고, 이는 문제를 더 악화시키는 원인이 됨

    • 언급한 점에 전적으로 동의함
      CPU utilization의 선형적이지 않다는 성질 때문에 % 자체가 실제와 괴리 생김
      즉, % 단위로 측정한 CPU utilization만이 거짓이라는 주장임

    • 만약 두 개의 워크로드가 모두 100% CPU 사용량을 기록하지만, 한 쪽은 훨씬 더 많은 전력을 소모하고 CPU 온도도 확 올린다면, 실제론 그 워크로드가 더 많은 트랜지스터 자원을 활용하는 것 아닌가 하는 의문이 생김

  • CPU utilization이 완벽하지 않은 척도이더라도 실용적으로는 유용하게 쓸 수 있었음
    간단한 SRE 업무 경험에서도 CPU 바운드 태스크 기준, 큐잉 이론에 CPU utilization 수치를 접목해 대규모 이벤트 전에 서버 규모를 산정했고, 더 "전통적"인 접근 대신 훨씬 보수적으로 제안한 %CPU 기준으로도 결과가 훨씬 비용 효율적으로 잘 나옴
    핵심은, 약간 부정확한 척도라도 현장에 쓸만하면 과하게 걱정하지 않고 활용해 보라는 거임
    다만 production 환경의 CPU utilization은 반드시 40%를 넘지 않게 유지한 이유는 다양한 상황에서 약간의 headroom을 확보해두기 위함임
    저자에게 "높은 utilization을 큐잉 이론적으로 피하는" 논리적 근거가 부족하다는 점이 아쉬움

    • 약간 허술한 지표라도 현장에서 적절하게 쓰이면 충분하다고 생각함
      예를 들어, 각 호스트별 percentile metric의 단순 평균/최댓값을 그냥 쓰거나, 호스트 단위 히스토그램을 최종 집계할 때 percentile로 계산하더라도, 실무적으로 둘 사이의 전환이 실제 운영에 큰 차이를 안 내더라고 경험함
      수학적으로 엄정하게 맞다 틀리다를 너무 신경 쓰는 일부 사람들이 있지만, 현실 운영에는 큰 영향 없는 경우도 많음

    • 40%면 사실 꽤 느슨한(여유 많은) 활용률이라는 생각임

    • CPU%와 loadavg를 함께 보면 시스템 상태를 꽤 잘 파악할 수 있다고 생각함
      loadavg가 높으면서 CPU%이 낮으면, 네트워크 또는 I/O에 걸리거나, 시스템 콜 등으로 대기 중일 수 있음
      이럴 경우 단순히 CPU%만 보면 고생하고 있는 부분을 놓칠 수 있음

    • 완전 똑같은 이야기를 들은 적이 있다고 느낌
      저자가 언급한 내용은 큐잉 이론 서적에 수십 년째 반복되어 온 내용임에도 불구하고, 이제서야 발견한 듯이 쓴 점이 신기함

  • Brendan Gregg의 "CPU Utilization is Wrong" 글이 생각남
    이 블로그의 핵심은 CPU utilization이 CPU가 바쁘다는 "상황"만을 지표로 삼으며 심지어 CPU가 대기 상태일 때도 busy로 간주함에 있음
    그리고 IPC는 이 busy한 상태 속에 숨겨진 실제 유효 작업량을 파악하는 척도임

    • 왜 Brendan이라는 이름을 가진 사람들은 CPU utilization 문제에 관심이 많은지 궁금함
      혹시 또 다른 Brendan이 있다면 설명해줄 수 있기를 바람
  • 하이퍼스레드가 제공하는 성능을 두 배로 계산해선 안 된다고 생각함
    실제 현실에서는 하이퍼스레드를 잘 활용해도 15~30% 정도만 성능이 추가되는 경우가 많았음. 대신, 레이턴시는 두 배가 될 수 있음
    core utilization이 높아질 때 클럭 저하도 반드시 고려해야 하므로, 현실에서는 비선형적이라는 것에 항상 주의함
    OS가 제공하는 정보만 가지고도 하이퍼스레드 효과와 클럭 저하까지 계산하면 훨씬 더 정확한 utilization 추정이 가능함
    그 이상으로 캐시/메모리 대역폭 제한이나 파이프라인 스톨이 성능 저하로 이어지는 현상까지 모델링하는 것도 어려운 일은 아니라고 봄

    • 상황을 복잡하게 만드는 요인으로, 하이퍼스레드 효율이 CPU 아키텍처·워크로드마다 천차만별임
      예를 들어 AMD(특히 최신 Zen) 구현은 Intel보다 훨씬 독립된 성능을 내는 편임(메모리 대역폭 병목이 없다는 가정 하에)

    • 메모리 바운드 애플리케이션이면 하이퍼스레드로 더 좋은 scaling을 보기 쉬움
      이 전에 담당했던 렌더러 프로젝트는 메모리 바운드라 하이퍼스레드만으로도 60~70% 성능 상승 효과를 경험함

    • 예전에 i7-3770K (4C/8T)에서 POV-Ray로 간단한 벤치마크를 돌린 적 있음
      1스레드→2스레드는 딱 두 배, 2→4에서도 두 배, 4→8에서는 겨우 15% 상승에 그침
      캐시 미스를 인위적으로 반복하는 특이 벤치마크라면 SMT에서 거의 두 배 성능을 끌어낼 수도 있을 것 같긴 한데 현실성은 의문임
      덧, POV-Ray 테스트를 다시 돌려볼까 고민 중임. 정말 오랜만이라 그리움

  • 저자가 %CPU utilization 수치에 따라 성능이 선형적으로 늘지 않는다는 점을 깨닫고, 결과적으로 %CPU utilization 자체가 "거짓"이라고 결론내린 것 같음
    하이퍼스레드, 클럭저하 없이도, 애플 실리콘 같이 변수가 적다고 생각되는 경우에도 정확히 비례한 scaling이 나오지 않음
    여러 코어를 동시에 쓰기 시작하면 데이터 전달 오버헤드 등 CPU 이외의 자원 병목이 빈번하게 문제를 일으켜 비슷한 상황이 자주 발생

    • Apple silicon도 특히 팬이 없는(수동 냉각) 모델에서는 클럭이 상당히 떨어짐
  • 저자가 사용하는 코어 용어가 혼란스럽고 표준과 다름
    5900X를 24코어 시스템으로 지칭하는데, 실제로는 12개 물리 코어에 24개 하이퍼스레드가 동작하는 구조임
    12개가 물리적 코어고 나머지 12개는 각각의 코어에 붙어서 구동되는 스레드임
    Instruction pipeline이 2세트라도 내부 functional unit을 공유함

    • 몇 년 전, 하이퍼스레딩을 잘 모르는 동생에게 설명해주려다 나온 비유 중 기억에 남는 것이, 마치 2겹 두루마리 휴지 같다는 말이었음
      24개를 따로 떼어낼 수는 없지만, 12개짜리를 두 배로 유용하게 쓰는 것과 비슷함

    • 피드백을 듣고 12코어/24스레드로 기술을 수정함
      다만, 내 OS가 활용률을 24코어로 표시하다 보니 헷갈리던 점이 있었음

    • 인텔이 소프트웨어 정의 코어를 내놓는다면 흥미로울 것 같음
      하이퍼스레딩의 논리적 반대로, 두 개 이상의 코어가 리소스를 공유해서 ‘하나의 큰 코어’로 변환되는 구조임
      아래 특허 링크를 참고함
      https://patents.google.com/patent/EP4579444A1/en

    • SMT 쌍이 똑같은 종류의 워크로드를 실행하면 내부 리소스와 실행 유닛 경합 현상 때문에 SMT 효과가 떨어짐
      만약 workload가 완전히 다르면 오히려 boost가 더 커질 수 있음
      이제는 최신 CPU에서는 P코어, E코어, 터보/비터보 등 변수까지 들어오면 상황이 더 복잡해짐
      SMT 추가가 터보 추가보다 와트당 성능 향상 효과가 크다는 연구가 있었는데, 매우 흥미로웠음

  • 정말 공감 가는 얘기임
    예전 어느 날, 서버 CPU가 60%까지 찼는데 더는 여유가 없다고 매니저에게 설명하니 뭔가 이상한 표정으로 쳐다봤음
    그때 딱 이런 설명이 있었으면 좋았을 것 같음

    • 큐잉 이론을 함께 설명해주면 효과 만점임
      60% 미만에선 큐잉 지연이 사실상 무시할 수 있는 수준
      70%리 넘어가면서 지연이 확 느껴지고, 80%부턴 거의 배가 됨
      실제 내 경험에서는 P95 타임 기준 65%를 목표로 맞췄고, 이게 이론적 기준과 거의 일치함
      결론적으로 "60%가 사용량 한계, 80%부터 지연이 폭증"이 실무 룰임

    • 하지만 워크로드에 따라 완전히 달라질 수 있음
      특히 요즘처럼 서버 CPU가 32코어씩 되는 시대에선 더 그렇다고 봄

  • CPU utilization이 기대한 대로 동작하지 않는 경우가 많음
    원래 이런 유형의 글이면 Linux/Windows 상에서 Utilization 수치가 도는 이야기를 예상했으나, 실제론 RAM 병목 때문에 CPU는 한가롭게 대기 혹은 다운클럭된 사례도 많음
    실제로 CPU utilization은 OS가 (Windows든 Linux든) 각 코어에 스레드를 얼마나 할당하냐만을 따지는 것임
    그런데 이 스레드가 memcpy에서 100% 대기 중이어도 utilization로 기록됨
    하이퍼스레드 장점이란, 한 쪽 스레드가 AVX/벡터 유닛에 묶여 있고, 다른 스레드가 단순 memcpy/RAM에 묶여 있으면, 각각의 유닛 활용도를 끌어올려 전체적인 성능과 utilization을 올릴 수 있음
    결론적으로 CPU Utilization은 오랫동안 직관적으로 이해하기 힘든 주제로, 매번 새로운 관점이 계속 발견됨
    그래도 항상 재미있는 주제임

  • 하이퍼스레드 코어가 진짜 코어와 똑같이 동작한다고 믿는 게 진짜 "거짓"임
    결국 20년 넘게 계속 쓰다 보니 원래의 본질을 잊고, 성능 측정값이 왜 이상한지 반복적으로 깨달음
    또 한 가지는, 프로세서는 근본적으로 "실행 중"(100%) 아니면 "대기 중"(0%) 뿐임
    그 중간에 %를 부여한다는 것 자체가 특정 시간 단위의 평균값에 불과하다는 점을 다시 생각하게 됨

  • 예전에 이런 대화를 나눴던 경험이 있음
    매니저: CPU utilization이 100%니까 서버를 더 큰 인스턴스로 바꿔야 하지 않겠냐고 물음
    나: "근데 지금 CPU가 진짜 쓸모 있는 작업을 하고 있긴 한가요?"
    결과적으론 busy waiting도 CPU utilization로 기록되기 때문에, 실제 유효 작업과 무관하게 숫자만 올라가는 경우임

맞는 표현임.