본문 바로가기
System/Computer Architecture

RISC와 CISC, 명령어 집합 구조 | 프로그래머가 몰랐던 멀티코어 CPU 이야기, 김민장 저

by wanggoNya 2024. 8. 20.

 

     ※  아래 내용은 스스로 공부한 내용을 정리한 글입니다.
     ※  때로 정확하지 않을 수 있으며, 참고만 부탁드립니다.
     ※  잘못된 내용이 있을시 댓글로 알려주시면 감사하겠습니다.
     ※  해당 글은 『김민장 저, 프로그래머가 몰랐던 멀티코어 CPU 이야기』를 읽고 정리한 글입니다.

 

 

 

요즘 시스템 분야에 흥미를 느껴서 김민장 님 저서인 『프로그래머가 몰랐던 멀티코어 CPU 이야기』를 읽기 시작했습니다. 하루에 한 챕터씩 읽으면서 글과 실물의 괴리감을 줄이기 위해 간단한(?) 사이드 프로젝트도 함께 해볼까 하는데 시간이 가능할지 모르겠네요. 그래도 오래간만에 가슴 뛰는 공부 거리를 찾았습니다. 

 


 

명령어 집합 구조, 즉 프로세서 언어인 ISA를 대표적인 두 축 RISC와 CISC를 중심으로 알아보자.

 

복잡한 형태의 ISA, CISC(Complex Instruction Set Computer)

프로세서, 다시 말해 범용 목적 마이크로 프로세서(general purpose microprocessor)가 처음 탄생했던 1970년대에는 컴파일러의 도움이 크지 못했다. 그렇기에 프로세서 설계자는 프로그래밍 언어와 1:1 대응이 될 정도로 풍부한 여러 명령어를 제공하려고 했다.

심지어는, x87 산술 보조프로세서의 명령에서 sin과 exp 같은 초월함수까지 담고 있었는데, 그 이유는

1. 소프트웨어로 이런 삼각 함수를 계산하는 것보다 하드웨어가 바로 처리하는 것이 더 빨랐기 때문이다.

2. 이 당시는 메모리가 매우 비싸던 시절이라 조금이라도 명령어 크기를 줄여야 했다.

그래서 짧은 길이의 명령어많은 뜻을 함축하도록 설계되었다. 이런 이유로 최초의 ISA는 CISC, Complex Insrtuction Set Computer라는 복잡한 형태를 띠게 되었다.

대표적인 예로, 인텔의 x86 명령어 구조, DEC 사의 VAX(Virtual Address Extension) 명령어 구조가 있다.

 

x86 ISA

- 1986년 출시

- 인텔 80386 ISA

- IA-32 (Intel Architecture 32 bit)라고도 함.

- 하위 호환성 (그 이전에 나온 16 bit 코드도 호환)

- 표준 지원 (AMD가 제안한 x86의 64 bit 확장, AMD64, x86-64, Intel64라고도 한다.) 

 

CISC의 주요 특징

1. 명령어 길이가 주로 가변적이다.

2. 여러 복잡한 형태의 주소 모드의 지원

3. 범용 레지스터의 개수가 비교적 적다. (GPR, General Purpose Register이라고도 한다.)

4. x86 32 bit는 EAX, EBX와 같은 레지스터로 8개만 제공한다. 여기에 x86-64는 8개가 추가되어 총 16개의 GPR, 범용 레지스터가 있다.

 

RISC (Reduced Instruction Set Computer)의 등장

위에서 설명한 CISC는 RISC로 넘어가게 된다. 그 이유는 1970년대 IBM 연구자들에서 시작한다.

1. 명령어 종류가 그렇게 많지 않다는 사실을 밝혀냈다.

(컴파일러가 CISC 명령어 집합이 지원하는 모든 명령어와 주소 모드를 사용하지 않고 일부만 자주 사용함)

2. CISC가 과도하게 설계되었다. 

프로그램 코드에는 상수가 자주 등장한다. 사칙 연산의 피연산자에 들어가는 상수, 또 분기문의 목적지로 표현되는 상수 같이 말이다. CISC는 가변 길이라서 16 bit와 32 bit 상수 피연산자를 쉽게 명령어에 포함시킬 수 있다.

그러나 대부분의 프로그램이 13 bit면 충분히 상수를 표현할 수 있었다. 1,234,567,890 같은 엄청나게 큰 정수보다는 -1, 10 같은 작은 정수들이 자주 나온다는 것이다.

3. 프로그램이 분기문으로 실행 흐름을 바꾸려면 그 목적지를 기술해야 한다. 대부분 절대 위치보다는 상대 위치다. 상대 위치의 그 범위도 그렇게 크지 않다.

 

컴퓨터 구조 설계의 첫 번째 원칙을 생각하자.

"Meke Common Case Fast"

"자주 있는 경우를 빠르게 하라."

 

이것이 RISC가 등장한 이유다. 자주 쓰이지 않는 명령어 종류를 줄이고, 상수를 표현하는데 32 bit를 모두 쓸 필요가 없었기 때문에 RISC가 등장한 것. 바로 프로세서 구조의 단순함과 고속화를 위해 명령어 길이를 4 byte 정도로 제한해도 큰 문제가 없을 것이다.

 

RISC 철학, 그리고 특징

이런 철학이 태어난 게 70~80년대이다. 이 때는 지금의 반도체 기술보다 한참이나 뒤처진 때다. 간단한 명령어는 그만큼 회로가 단순해져서 더 저렴한 비용으로 제조할 수 있다.

대신 소프트웨어 컴파일러가 일을 더 하게 된다. x86 명령에는 문자열을 받아서 내부적으로 루프 형태 처리를 하는 명령어도 있다. RISC에서는 컴파일러단순한 형태의 명령어 흐름으로 바꾸어 준다.

 

이렇게 해서, 다음과 같은 특징을 가진 RISC가 등장한다.

1. 실제로 사용하는 명령어 패턴은 훨씬 간단함.

2. 명령어 크기를 고정

3. 명령어 개수를 대폭 줄임

 

RISC 명령어 Set의 예시는 다음과 같다.

- 스마트폰에 쓰이는 ARM

- IBM의 PowerPC

- 학교에서 주로 배우는 MIPS (Microprocessor without Interlocked Pipeline Stages)

 

 

대표적인 RISC, MIPS 구조

MIPS 구조를 알아보면 RISC의 대표적인 특징도 살펴볼 수 있다. MIPS는 모든 명령어의 길이가 32 bit로 고정되어 있고 매우 규칙적인 포맷을 갖고 있다. 모든 명령어가 다음 3가지 타입으로 표현된다.

- R (Register)

- I (Immediate)

- J (Jump)

여기서 I는 Immediate로, "상수"를 가리킨다. 명령어 자체에 포함되어 있는 상수를 '즉시' 읽어올 수 있기 때문에 이런 표현을 쓰는 것. 

 

이 세 가지 명령어 타입을 정리해보자.

종류/비트영역 31~26 25~21 20~16 15~11 10~6 5~0
R Opcode source target destination shift function
I Opcode source target 16-bit 상수(immediate)
J Opcode 26-bit 분기 목적지

표 2-1 MIPS 명령어 타입 및 구성

 

opcode, operation code는 위 표에서 볼 수 있듯이 어떤 명령어인가를 기술하고 있는 코드로, 항상 최상위 6 bit에 존재한다. 이 말은 주어진 임의의 명령어를 분석할 때 그만큼 간단하게 예외 없이 처리할 수 있다는 소리다.

대신 x86 opcode의 위치, 길이가 가변적이어서 분석 작업이 훨씬 복잡해진다. 이는 필연적으로 하드웨어 회로의 복잡함으로 이어진다.

 

2장 정리 중입니다.

 


[ Reference ]

프로그래머가 몰랐던 멀티코어 CPU 이야기 (김민장 저) 

"챕터 2장, 프로세서의 언어 : 명령어 집합 구조 " 中