핵심 인사이트 (3줄 요약)
- 본질: 간접 사이클 (Indirect Cycle)은 명령어가 직접 데이터가 있는 곳이 아니라, 실제 주소가 저장된 위치를 가리킬 때 한 번 더 메모리를 읽어 유효 주소 (Effective Address, EA)를 확정하는 단계다.
- 가치: 이 과정 덕분에 짧은 명령어 주소 필드만으로도 큰 주소 공간과 동적 자료구조를 다룰 수 있어, 포인터 기반 소프트웨어와 하드웨어 주소 지정 방식이 연결된다.
- 판단 포인트: 간접성은 유연성을 주지만 메모리 접근을 추가로 요구하므로, 현대 마이크로아키텍처에서는 전용 간접 사이클보다 캐시, 주소 생성, 로드-로드 연쇄 최적화로 비용을 줄이는 관점이 중요하다.
Ⅰ. 개요 및 필요성
간접 사이클 (Indirect Cycle)은 해독 사이클 (Decode Cycle)에서 명령어의 주소 지정 방식이 간접 주소 지정 (Indirect Addressing) 으로 판별되었을 때, 실행 전에 실제 피연산자 위치를 알아내기 위해 수행하는 보조 단계다. 즉 명령어 안의 주소가 곧바로 데이터의 주소가 아니라, "진짜 주소가 들어 있는 메모리 칸"의 주소일 때 한 번 더 확인하는 절차다.
이 개념이 필요해진 이유는 초기 컴퓨터의 명령어 길이가 짧아, 명령어 안에 충분히 긴 절대 주소를 매번 담기 어려웠기 때문이다. 직접 주소만 쓰면 명령어 형식은 단순하지만 주소 공간 확장성과 데이터 구조 유연성이 떨어진다. 반대로 간접 참조를 허용하면 주소 자체를 메모리에 보관해 둘 수 있어, 하나의 명령 형식으로 더 넓은 메모리 공간과 가변적인 데이터 배치를 다룰 수 있다.
또한 간접 사이클은 포인터 (Pointer), 연결 리스트 (Linked List), 함수 테이블 같은 소프트웨어 개념을 기계 수준에서 가능하게 하는 다리 역할을 한다. 데이터가 자주 이동하거나 실행 중 참조 대상이 바뀌는 환경에서는 명령어를 수정하지 않고도 메모리 속 주소값만 바꿔 동작 대상을 전환할 수 있다. 없으면 하드웨어는 유연성을 잃고, 프로그램은 고정된 주소에 더 강하게 묶인다.
┌────────────────────────────────────────────────────────────────────────────┐
│ 직접 참조와 간접 참조의 차이 │
├────────────────────────────────────────────────────────────────────────────┤
│ 직접 주소 지정 │
│ 명령어 주소부 ───────────────▶ 실제 데이터 주소 │
│ │
│ 간접 주소 지정 │
│ 명령어 주소부 ─▶ 주소가 저장된 메모리 칸 ─▶ 실제 데이터 주소 │
│ (한 번 더 읽기 필요) │
└────────────────────────────────────────────────────────────────────────────┘
핵심은 간접 사이클이 데이터를 읽는 단계 이전에 주소를 한 번 더 해석하는 시간이라는 점이다. 즉 추가 비용은 연산 때문이 아니라, "어디를 읽어야 하는가"를 최종 확정하기 위한 주소 추적 때문에 생긴다.
- 📢 섹션 요약 비유: 집에 바로 가는 대신, 먼저 안내 데스크에 들러 "친구가 지금 어느 방에 있는지"를 물어보고 다시 움직이는 과정이 간접 사이클이다. 한 번 더 걸어야 하지만, 친구가 방을 옮겨도 안내판만 바꾸면 된다.
Ⅱ. 아키텍처 및 핵심 원리
간접 사이클의 핵심 구성 요소는 프로그램 카운터 (Program Counter, PC), 명령어 레지스터 (Instruction Register, IR), 메모리 주소 레지스터 (Memory Address Register, MAR), 메모리 버퍼 레지스터 (Memory Buffer Register, MBR) 또는 메모리 데이터 레지스터 (Memory Data Register, MDR)다. 인출과 해독이 끝나면 제어 유닛은 IR의 간접 비트와 주소 필드를 보고, 해당 주소를 그대로 실행하지 말고 한 번 더 메모리를 읽으라고 지시한다.
| 구성 요소 | 역할 | 간접 사이클에서의 의미 |
|---|---|---|
| IR | 현재 명령어 보관 | 주소 필드와 간접 비트 확인 |
| MAR | 메모리에 제시할 주소 보관 | 먼저 "주소가 저장된 위치"를 넣음 |
| MBR/MDR | 메모리에서 읽어 온 값 보관 | 읽어 온 값이 데이터가 아니라 EA가 됨 |
| 제어 유닛 (Control Unit) | 순서 제어 | 추가 메모리 읽기 여부 결정 |
전형적인 마이크로 오퍼레이션은 아래와 같이 정리할 수 있다.
┌────────────────────────────────────────────────────────────────────────────┐
│ 간접 사이클의 전형적 마이크로 오퍼레이션 │
├────────────────────────────────────────────────────────────────────────────┤
│ 전제 : IR의 주소부 = A, 간접 비트 I = 1 │
│ │
│ T0 : MAR ← IR(Address) │
│ T1 : MBR ← M[MAR] ; 메모리에서 실제 주소(EA) 읽기 │
│ T2 : IR(Address) ← MBR ; 또는 EA Register ← MBR │
│ T3 : Execute 단계로 진입 ; 확정된 EA를 사용해 피연산자 접근 │
└────────────────────────────────────────────────────────────────────────────┘
이 흐름은 "메모리에서 데이터를 읽는다"와 "메모리에서 주소를 읽는다"가 하드웨어적으로 같은 read 동작이지만, 의미가 다르다는 점을 보여준다. 첫 번째 read의 결과는 연산 대상 값이 아니라 다음 read에 사용할 주소다. 그래서 간접 사이클은 주소 해석의 재귀를 1단계 확장한 것으로 이해하면 좋다.
아래 그림은 명령어 하나가 실제 데이터를 얻기까지 어떤 경로를 거치는지 보여준다.
┌────────────────────────────────────────────────────────────────────────────┐
│ 간접 사이클에서 주소가 확정되는 흐름 │
├────────────────────────────────────────────────────────────────────────────┤
│ PC ─▶ 명령어 인출 ─▶ IR = LOAD @A │
│ │ │
│ ▼ │
│ MAR ← A │
│ │ │
│ ▼ │
│ 메모리[A] = EA 값을 읽음 │
│ │ │
│ ▼ │
│ IR 주소부 또는 EA 레지스터 갱신 │
│ │ │
│ ▼ │
│ 메모리[EA]에서 실제 데이터 접근 │
└────────────────────────────────────────────────────────────────────────────┘
이 구조의 병목은 분명하다. 직접 주소 지정이라면 메모리[EA]만 읽으면 되지만, 간접 주소 지정은 그 전에 메모리[A]를 먼저 읽어야 한다. 캐시가 없는 고전 구조에서는 메모리 지연이 그대로 한 번 더 붙고, 캐시가 있는 현대 구조에서는 포인터가 가리키는 위치가 예측 불가능할수록 적중률이 떨어져 지연이 커진다.
- 📢 섹션 요약 비유: 간접 사이클은 사물함 열쇠를 찾기 위해 먼저 관리실에서 열쇠 번호표를 받아 오는 과정과 같다. 관리실 방문이 한 번 추가되므로 느려지지만, 번호표만 바꾸면 다른 사물함도 같은 절차로 열 수 있다.
Ⅲ. 비교 및 연결
간접 사이클의 특징은 직접 주소 지정 (Direct Addressing)과 비교할 때 가장 선명해진다. 직접 주소는 빠르고 단순하지만 명령어 주소 필드가 곧바로 실제 위치를 지정해야 한다. 간접 주소는 메모리 참조가 늘어나는 대신, 주소값을 메모리에 따로 보관해 참조 대상을 유연하게 바꿀 수 있다.
| 비교 항목 | 직접 주소 지정 | 간접 주소 지정 |
|---|---|---|
| 실제 메모리 참조 수 | 보통 1회 | 보통 2회 이상 |
| 주소 필드 활용 | 큰 주소 공간에 불리 | 작은 필드로도 넓은 공간 참조 가능 |
| 데이터 구조 유연성 | 낮음 | 높음 |
| 파이프라인 친화성 | 상대적으로 높음 | 포인터 의존성 때문에 낮아짐 |
이 차이는 파이프라이닝과도 직접 연결된다. 파이프라인에서는 다음 단계가 미리 진행돼야 처리량이 높아지는데, 간접 주소는 실제 접근 위치가 추가 메모리 read가 끝나야 확정된다. 따라서 주소 생성이 늦어지고, 뒤따르는 로드/실행 단계는 데이터 해저드 (Data Hazard)와 구조적 지연에 더 민감해진다.
현대 RISC (Reduced Instruction Set Computer) 계열이 고전적 의미의 "전용 간접 사이클"을 약화시키는 이유도 여기에 있다. 복잡한 주소 추적을 명령어 하나의 내부 상태 기계로 숨기기보다, load pointer 후 load data처럼 단순 명령어 둘로 쪼개어 파이프라인 제어와 컴파일러 스케줄링을 쉽게 만드는 편이 유리하기 때문이다. 반면 CISC (Complex Instruction Set Computer) 계열은 다양한 주소 지정 모드를 지원해 같은 동작을 명령어 수준에서 더 풍부하게 제공해 왔다.
소프트웨어 관점에서는 간접 사이클이 곧 포인터 역참조와 맞닿아 있다. *p는 "p가 담고 있는 주소로 다시 가서 읽어라"는 뜻이므로, 하드웨어 입장에서는 주소를 한 번 따라가는 행동이다. 운영체제의 페이지 테이블 탐색, 인터럽트 벡터 참조, 객체지향 언어의 가상 함수 테이블 접근도 본질적으로는 이 간접성의 확장된 사례다.
- 📢 섹션 요약 비유: 직접 주소는 집 주소를 종이에 바로 써서 택배를 보내는 방식이고, 간접 주소는 먼저 "배송 대행지"에 보내고 거기서 최종 주소를 확인해 다시 보내는 방식이다. 유연성은 커지지만 경유지가 늘어 시간이 더 든다.
Ⅳ. 실무 적용 및 기술사 판단
실무나 기술사 답안에서는 간접 사이클을 단순 정의로 끝내기보다, 어디서 성능 비용이 터지고 왜 아직도 필요한가를 함께 말해야 한다. 가장 대표적인 사례는 포인터 체인이 긴 자료구조다. 연결 리스트, 트리, 해시 버킷, 페이지 테이블 워크처럼 "주소를 따라가야 다음 주소가 보이는" 구조는 메모리 지역성 (Locality)이 약해 캐시 미스와 지연이 누적되기 쉽다.
판단 체크리스트
- 간접 참조가 한 번인지, 다중 단계인지 파악했는가?
- 포인터가 가리키는 위치가 캐시 친화적으로 배치되어 있는가?
- 파이프라인에서 주소 확정 지연 때문에 로드-유즈 스톨이 커지지 않는가?
- 하드웨어에 복잡한 주소 지정 모드를 넣는 것보다 컴파일러/소프트웨어로 분해하는 편이 더 단순하고 예측 가능한가?
대표 적용 사례
- 인터럽트 벡터 테이블: 인터럽트 번호로 엔트리를 찾고, 그 엔트리에 저장된 서비스 루틴 주소로 이동한다.
- 페이지 테이블 탐색: 가상 주소를 실제 물리 주소로 바꾸기 위해 여러 단계의 주소 테이블을 따라간다.
- 가상 함수 호출: 객체 안의 가상 함수 테이블 포인터를 읽고, 다시 그 테이블에서 실제 함수 주소를 읽는다.
안티패턴
- 포인터 체인을 깊게 설계해 메모리 접근 지연을 연쇄적으로 키우는 경우
- 배열로 평탄화할 수 있는 구조를 불필요하게 링크 구조로 만들어 캐시 효율을 떨어뜨리는 경우
- 복잡한 간접 주소 지정을 "명령어 수 감소"만 보고 채택해, 실제 파이프라인 비용과 검증 복잡도를 과소평가하는 경우
결론적으로 간접 사이클은 기능적으로 유용하지만, 성능 설계에서는 늘 "유연성 대 지역성"의 trade-off로 봐야 한다. 주소 한 번 더 읽는 비용은 작은 것처럼 보여도, 주기적으로 반복되면 전체 처리량을 크게 깎을 수 있다.
- 📢 섹션 요약 비유: 간접 참조를 많이 쓰는 프로그램은 골목마다 안내 표지판을 보고 다시 방향을 정하는 배달원과 같다. 길은 유연하게 바꿀 수 있지만, 표지판이 많아질수록 배송 시간은 늘어난다.
Ⅴ. 기대효과 및 결론
간접 사이클이 제공하는 가장 큰 효과는 주소 공간 활용의 유연성과 자료구조 표현력 향상이다. 명령어가 모든 실제 주소를 직접 품지 않아도 되므로, 제한된 명령어 형식으로도 큰 메모리 체계를 다룰 수 있다. 또한 데이터 재배치, 동적 연결, 포인터 기반 구조를 지원해 소프트웨어 설계 자유도를 높인다.
하지만 이 장점은 추가 메모리 접근과 더 어려운 성능 예측을 대가로 얻는 것이다. 특히 현대 프로세서에서는 평균 메모리 지연보다 캐시 미스 패널티가 훨씬 커졌기 때문에, 간접성이 많은 코드는 계산량보다 메모리 대기 시간에 더 지배될 수 있다. 그래서 최근 설계는 전용 간접 사이클 자체를 강조하기보다, 캐시 계층·프리페치 (Prefetch)·로드 스케줄링·데이터 평탄화로 그 비용을 줄이는 쪽으로 발전한다.
기억해야 할 관점은 단순하다. 간접 사이클은 "한 번 더 돌아가는 비효율"이 아니라, 주소를 데이터처럼 다루게 만든 유연성의 대가다. 시험에서는 주소 확정 단계라는 본질을, 실무에서는 포인터 추적과 메모리 지연의 비용이라는 판단 포인트를 함께 잡으면 된다.
- 📢 섹션 요약 비유: 간접 사이클은 여행 계획표를 매번 새로 쓰지 않고, 안내 센터에 최신 목적지만 바꿔 두는 방식과 같다. 일정은 유연해지지만, 출발 전 안내 센터를 들르는 시간은 반드시 필요하다.
📌 관련 개념 맵
| 개념 | 연결 포인트 |
|---|---|
| 주소 지정 방식 (Addressing Mode) | 간접 사이클은 간접 주소 지정이 선택되었을 때만 나타나는 보조 단계다. |
| 명령어 사이클 (Instruction Cycle) | 인출-해독-실행 흐름 중, 해독과 실행 사이에서 실제 주소를 확정한다. |
| 유효 주소 (Effective Address, EA) | 간접 사이클의 직접 산출물이며, 이후 실행 단계의 실제 접근 기준이 된다. |
| 포인터 (Pointer) | 메모리에 저장된 주소를 다시 따라간다는 점에서 소프트웨어 수준의 대응 개념이다. |
| 데이터 해저드 (Data Hazard) | 실제 주소 확정이 늦어질수록 뒤따르는 명령어가 대기하게 된다. |
| 캐시 미스 (Cache Miss) | 간접 참조가 예측 불가능한 메모리 위치를 따라갈수록 성능 손실이 커진다. |
📈 관련 키워드 및 발전 흐름도
직접 주소 지정 중심의 단순 메모리 접근
│
▼
간접 주소 지정 (Indirect Addressing)
│
▼
유효 주소 (Effective Address, EA) 확정용 간접 사이클
│
▼
포인터 (Pointer) · 인터럽트 벡터 · 페이지 테이블
│
▼
캐시/파이프라인 관점의 포인터 추적 최적화
│
▼
RISC 기반 로드 분해 · 프리페치 · 데이터 평탄화 전략
이 흐름은 주소를 즉시 해석하던 구조에서 출발해, 주소를 메모리 안의 데이터로 다루고, 다시 그 비용을 현대 마이크로아키텍처가 최적화하는 방향으로 발전해 온 과정을 보여준다.
👶 어린이를 위한 3줄 비유 설명
- 간접 사이클은 상자를 열었더니 장난감이 바로 있는 게 아니라, "장난감은 3번 서랍에 있어"라는 쪽지가 들어 있는 상황이에요.
- 그래서 먼저 쪽지를 읽고, 그다음 진짜 서랍으로 한 번 더 가야 장난감을 찾을 수 있어요.
- 조금 느리지만 쪽지만 바꾸면 장난감 위치를 쉽게 바꿀 수 있어서 아주 유연한 방법이랍니다.