ABOUT

성능과 운영 안정성을 함께 끌어올리는 개발자입니다.

92% Positional Error Reduction
79% p95 Latency Improvement
90%+ Long Tasks Reduction

2022.02 · 한국장학재단

우수 멘티

한국장학재단 사회 리더 대학생 멘토링 IT

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

(주) 그랩 우수 프로그램 개발

2025.05 · AWSKRUG

AWS한국사용자모임 발표

AI agent 스크립트 튜닝 관련 발표

ComputerScience

Development

Engineering

Trouble Shooting

GUESTBOOK

첫 마음부터
함께 나누는 온기

방명록 작성하러 가기

SUBSCRIBE

최신소식을
편하게 만나보세요.

레지스터 (Register)

정의

CPU 내부의 초고속 작업 공간

레지스터는 CPU 안에 있는 가장 빠른 저장소입니다. 명령어 실행에 필요한 값(피연산자/주소/상태)을 레지스터에 올려두면, CPU는 메모리 대기 없이 연산을 이어갈 수 있습니다.

정리하면, 레지스터를 이해한다는 것은 CPU가 어디서 값을 쓰고(GPR), 어떤 명령을 실행 중이며(IR), 다음에 어디로 갈지(PC), 분기 판단을 어떻게 하는지(FLAGS/FR)를 이해하는 것과 같습니다.

핵심 메시지

“빠른 CPU는 연산보다 데이터를 레지스터에 올려두는 방식에서 갈린다.”

- 레지스터는 CPU의 ‘가장 가까운 책상’이다 -

종류

프로그램 카운터(PC/IP) 

PC(또는 IP)는 메모리에서 다음으로 가져올(fetch) 명령어의 위치를 가리킵니다. 일반적으로 한 번의 명령어 실행이 끝나면 PC는 다음 명령어 주소로 증가합니다(예: +4).

단, 분기/점프/함수 호출/예외 같은 제어 흐름이 발생하면 PC는 분기 대상 주소로 갱신됩니다. 우리가 쓰는 if/for/while 같은 고수준 문법은 결국 “PC를 어디로 바꿀지”의 문제로 내려갑니다.

개발자 관점
조건문/루프/함수 호출은 모두 PC 변경으로 구현됩니다.
그래서 “분기 예측 실패” 같은 CPU 이슈는 결국 PC가 예상과 다르게 움직인 비용으로 이해할 수 있습니다.

 

레지스터 2

명령어 레지스터(IR) — 방금 가져온 명령어 자체

IR은 메모리에서 fetch된 명령어를 담습니다. CPU의 제어 장치는 IR에 들어온 명령을 디코딩(decode)한 뒤, ALU/로드·스토어/분기 등 필요한 실행 유닛에 제어 신호를 보냅니다.

참고로 현대 CPU는 파이프라인 단계마다 “명령어를 잡아두는 래치/버퍼”가 존재합니다. 글에서는 이해를 위해 이를 개념적으로 IR로 묶어 설명합니다.

PC vs IR 한 줄 비교
PC는 “다음 명령어의 위치(주소)”, IR은 “현재 실행할 명령어 내용”을 담습니다.

 

레지스터 3

범용 레지스터(GPR) — 데이터/주소/중간 결과를 담는 초고속 작업 공간

GPR은 연산 대상(피연산자), 중간 결과, 메모리 주소 등을 자유롭게 담을 수 있습니다. CPU 내부에 여러 개가 존재하며, 컴파일러는 레지스터 할당(Register Allocation)을 통해 가능한 한 변수를 레지스터에 두어 메모리 접근을 줄이려 합니다.

왜 “메모리 접근 최소화”가 핵심일까?
레지스터 접근은 메모리보다 훨씬 빠릅니다.
레지스터가 부족하면 값이 스택/메모리로 “spill(넘침)”되고, 그 순간부터 성능이 떨어질 수 있습니다.

// 감각적으로만 보기 (개념)
// a + b 같은 연산은 "값을 레지스터로 올리고" -> "ALU로 계산" -> "결과를 레지스터/메모리에 기록"
int c = a + b;

 

레지스터 4

스택 포인터(SP) — 함수 호출/복귀의 기준이 되는 스택 top 주소

SP는 “현재 스택의 꼭대기”를 가리킵니다. 함수 호출 시 리턴 주소, 지역 변수, 저장할 레지스터 등이 스택에 쌓이고, 복귀 시 다시 되돌립니다. 이 과정의 중심이 SP입니다.

일부 아키텍처/컴파일 옵션에서는 디버깅/스택 추적을 위해 프레임 포인터(FP/BP)를 별도로 두기도 합니다. (실무에선 “스택 트레이스/프로파일링/보안”과 연결됩니다.)

💡 TIP / 실무 연결

“함수 호출 규칙(Calling Convention/ABI)”은 결국
인자/리턴값을 어떤 레지스터로 전달하고, 부족하면 스택(SP)을 어떻게 쓰는지의 규칙입니다.

 

레지스터 5

플래그 레지스터(FLAGS/FR/PSR) — 연산 결과의 “상태”를 비트로 저장

플래그(flag)는 CPU가 명령어를 처리하는 과정에서 반드시 참조할 상태 정보를 의미합니다. 대표적으로 비교(compare) 이후의 조건 분기는 플래그 값을 보고 다음 실행 흐름(=PC 갱신)을 결정합니다.

플래그 의미 개발자 관점 예시
ZF (Zero) 결과가 0 비교 후 “같다/0이다” 판단에 자주 사용
예: if (a == b), while (x != 0)
SF (Sign) 결과 부호 signed 비교/분기에서 “음수 여부” 판단
예: if (x < 0) 같은 조건 흐름
CF (Carry) 자리올림/빌림 unsigned 연산 범위 초과 판단(캐리/빌림)
예: 32비트 unsigned 덧셈 overflow 감지
OF (Overflow) signed overflow signed 정수의 표현 범위 초과 감지
예: int 범위를 넘는 덧셈/뺄셈

CF와 OF는 자주 헷갈립니다. CF는 주로 unsigned 범위 초과(자리올림/빌림)이고, OF는 signed 표현 범위 초과(부호가 뒤집히는 형태)를 의미합니다.

 

실무 연결

레지스터는 컨텍스트 스위칭성능 최적화의 중심입니다.

스레드/프로세스를 바꿀 때 OS는 현재 실행 흐름의 레지스터 값(PC, SP, GPR, FLAGS 등)을 저장하고, 다음 실행할 흐름의 레지스터 값을 복구합니다. 이 저장·복구 묶음이 흔히 말하는 컨텍스트(context)입니다.

성능 관점에서는 “레지스터 부족 → spill → 메모리 접근 증가”가 병목으로 이어질 수 있습니다. 그래서 컴파일러 최적화(레지스터 할당), 코드의 분기 패턴, 데이터 지역성(캐시 적중률) 등이 실제 체감 성능에 영향을 줍니다.

💡 TIP / 한 줄 체크

“CPU가 빠른데도 느리다”는 상황은 보통 레지스터/캐시/메모리 계층에서 대기가 생긴 경우입니다. (락 경합, GC, 페이지 폴트, I/O 대기까지 포함해 병목을 분리해서 보세요.)

 

심화

레지스터 리네이밍(Register Renaming) — 의존성을 줄여 처리량을 올리는 기법

고성능 CPU는 “프로그램에 보이는 레지스터(아키텍처 레지스터)” 외에 내부적으로 더 많은 “물리 레지스터”를 두고, 동일 이름 레지스터의 가짜 의존성(Write-after-Read 등)을 줄이기 위해 리네이밍을 수행합니다. 덕분에 파이프라인이 더 바쁘게 일할 수 있어 처리량(throughput)이 좋아집니다.

정리
PC는 “다음 실행 위치(주소)”, IR은 “현재 명령어”, GPR은 “작업 공간”, SP는 “호출 스택의 기준”, FLAGS는 “판단 신호(분기 조건)”를 담습니다.
결국 레지스터를 이해하면 CPU가 무엇을 실행하고(IR), 어디로 흐름을 옮기며(PC), 어디에 값을 두고(GPR), 어떤 조건으로 판단하는지(FLAGS)가 한 번에 연결됩니다.

 

✅ 핵심 요약

  • ✔️ 레지스터는 CPU 내부의 초고속 저장소로, “지금 당장 쓰는 값”을 담는다.
  • ✔️ PC는 다음 명령어 주소, IR은 현재 명령어, GPR은 작업 공간, FLAGS는 분기 판단 신호다.
  • ✔️ 조건 분기/루프/함수 호출은 결국 PC 변경 + FLAGS 판단으로 구현된다.
  • ✔️ 컨텍스트 스위칭은 레지스터 상태 저장/복구가 핵심이며, 레지스터 부족(spill)은 성능에 불리하다.
728x90