축소 명령어 집합의 탄생
컴퓨터 구조
컴퓨터 구조를 공부하면서 알게된 내용을 요약해서 작성해보자.
시간이 흐르고 변화
- 기술이 발전하면서 메모리 용량 대비 가격이 급격히 떨어졌다. 이것이 첫 번째 흐름의 변화다.
- 컴파일러가 점점 발전하여 컴파일러에 의존하여 어셈블리어 명령어를 자동으로 생성했기에 직접 어셈블리어로 코드를 작성하는 방식은 더 이상 의미가 없어졌다. 이것이 두 번째 흐름의 변화다.
복잡함을 단순함으로
- 19세기 말 ~ 20세기 초, 빌프레도 파레토는 80-20 법칙을 발견했다.
- 파레토 법칙: 전체 결과의 80%가 전체 원인의 20%에서 일어난다.
- 기계 명령어 실행 빈도에도 비슷한 규칙이 있다.
- CPU는 약 80% 시간 동안 명령어 집합의 기계 명령어 중 20%를 실행한다.
- 복잡 명령어 집합에서 비교적 복잡한 명령어 중 일부는 자주 사용되지 않으며, 컴파일러를 설계하는 프로그래머는 고급 언어를 더 간단한 기계 명령어의 조합으로 변환하는 경향이 있다.
- 복잡 명령어 집합에서 성능을 향상시키는 것으로 여겨지는 명령어는 실제로 CPU 내부에서 마이크로코드에 의해 가로막힌다. 마이크로코드를 제거하면 오히려 프로그램이 더 빠르게 실행되고, CPU를 구성하는 데 사용되는 트랜지스터를 절약할 수 있다.
축소 명령어 집합의 철학
- 복잡 명령어 집합에 대한 반성을 바탕으로 축소 명령어 집합의 철학이 탄생했다.
- 다음 세 가지 측면에 주로 반영되었다.
- 명령어 자체의 복잡성
- 컴파일러
- LOAD/STORE 구조
- 명령어 자체의 복잡성
- 복잡한 명령어를 제거하고 간단한 명령어 여러 개로 대체한다.
- 이 사상으로 CPU 내부 마이크로코드 설계가 필요하지 않다.
- 마이크로 코드가 없으면 컴파일러에서 생성된 기계 명령어의 CPU 제어 능력이 크게 향상된다.
- 명령어 집합을 줄인다는 것은 명령어 집합의 명령어 개수가 줄어든다는 의미가 아니고, 하나의 명령어당 들여야 하는 연산이 더 간단하다는 의미다.
- 컴파일러
- 컴파일러가 CPU에 대해 더 강력한 제어권을 갖는다.
- 축소 명령어 집합을 사용하는 CPU는 더 많은 세부 사항을 컴파일러에 제공한다.
- 축소 명령어 집합은 흥미로운 작업을 컴파일러에 넘기기라는 이름으로 부르기도 한다.
- LOAD/STORE 구조
- 축소 명령어 집합의 명령어는 레지스터 내 데이터만 처리할 수 있다.
- 메모리 내 데이터는 직접 처리할 수 없다.
- LOAD와 STORE라는 전용 기계 명령어가 메모리의 읽고 쓰기를 책임진다.
- 다른 명령어들은 CPU 내부의 레지스터만 처리할 수 있으며, 메모리를 읽거나 쓸 수 없다.
복잡 명령어 집합과 축소 명령어 집합의 차이
- 두 숫자가 메모리 주소 A와 B에 저장된다. 이 두 숫자를 곱한 값을 계산한 후 계산 결과를 다시 메모리 주소 A에 기록하는 과정을 어떻게 구현되는지 알아보자.
- 복잡 명령어 집합의 경우
- 복잡 명령어 집합의 사상은 가능하면 적은 수의 기계 명령어로 가능한 많은 작업을 수행하는 것이다.
- 메모리 주소 A의 데이터를 읽어 레지스터에 저장한다.
- 메모리 주소 B의 데이터를 읽어 레지스터에 저장한다.
- ALU(산술 연산 장치)가 레지스터 값을 이용하여 곱셈 연산을 수행한다.
- 곱셈 결과를 다시 메모리에 저장한다.
- 명령어: MULT A B
- MULT 명령어 하나에는 메모리 읽기, 두 숫자 곱하기, 결과를 다시 메모리에 쓰는 작업이 포함되어 있다.
- 복잡한 명령어의 의미는 명령어 자체가 복잡한 것이 아니라 연산이 복잡하다는 의미다.
- 고급 언어와 매우 유사하다. 메모리 주소 A의 값을 a 변수로 가정하고 메모리 주소 B의 값을 b 변수로 가정하면 고급 언어에서 다음과 같이 작성한 코드와 기본적으로 동일하다. a = a * b;
- 이런 설계는 고급 언어와 기계 명령어 사이의 차이를 줄인다.
- 최소한의 코드로 작업을 완료하고 프로그램 자체가 차지하는 저장 공간을 절약하려는 목적이 있다.
- 축소 명령어 집합의 경우
- 일련의 간단한 명령어를 여러 개 사용하여 작업을 완료하는 것을 선호한다.
- 메모리 주소 A의 데이터를 읽어 레지스터에 저장한다.
- 메모리 주소 B의 데이터를 읽어 레지스터에 저장한다.
- ALU(산술 연산 장치)가 레지스터 값을 이용하여 곱셈 연산을 수행한다.
- 곱셈 결과를 다시 메모리에 저장한다.
- 명령어: LOAD, PROD, STORE
- LOAD 명령어는 메모리에서 레지스터로 데이터를 적재한다.
- PROD 명령어는 두 레지스터에 저장된 숫자의 곱셈 연산을 수행한다.
- STORE 명령어는 레지스터의 데이터를 다시 메모리에 쓴다.
- 복잡 명령어 집합을 사용할 경우 기계 명령어 하나가 필요한 반면에, 축소 명령어 집합을 사용하는 프로그램은 기계 명령어 네 개가 필요하다.
- 축소 명령어 집합 설계의 원래 의도는 프로그래머가 직접 어셈블리어로 코드를 작성하는 것이 아니라, 이 작업을 컴파일러에 맡기고 컴파일러가 구체적인 기계 명령어를 자동으로 생성하게 하는 것이다.
명령어 파이프라인
- 파이프라인 기술은 기계 명령어 하나가 실행되는 시간을 단축해 주지는 않지만 처리량을 늘릴 수 있다.
- 축소 명령어 집합은 모든 명령어의 실행 시간을 대체적으로 동일하게 하여 파이프라인이 더 높은 효율로 기계 명령어들을 처리할 수 있도록 한다. 이것이 축소 명령어 집합에 LOAD와 STORE라는 두 메모리 관련 전용 명령어가 있는 이유다.
축소 명령어 집합의 기회
- 축소 명령어 집합으로 설계된 CPU가 성능 면에서 기존 모든 전통적인 설계를 가볍게 진압했다.
- CPU 제조업체는 축소 명령어 집합을 따르고, 설계 사상을 적극 채택했다.