명령어 집합 | |
CISC | AMD64●x86● · M68K · 68xx · Z80 · 8080 · MOS 65xx · VAX |
RISC | AArch64 ARM · RISC-V● · MIPS● · DEC Alpha · POWER PowerPC · CELL-BE LoongArch · OpenRISC · PA-RISC · SPARC · Blackfin · SuperH · AVR32 AVR |
VLIW EPIC | E2K · IA-64 · Crusoe |
1. 개요
Complex Instruction Set Computer, CISC종류가 다양하고 하는 일이 복잡한 명령어로 이루어진 CPU, 또는 마이크로프로세서.
2. 특징
명령어의 길이가 가변적이기 때문에 명령어 밀도에서 유리한 편이다. 만약 데이터나 주소값이 필요하다면 명령어 길이를 늘려 해결한다. 하지만 RISC 구조에서는 길이를 늘릴 수도 없고 정해진 명령어 워드 길이 안에서 해결해야 한다. 그래서 복잡하다는 편견과 달리 CISC 구조는 명령어 세트 설계가 바이트 단위로 깔끔한 편이다.흔히 비파이프라이닝 방식을 사용하는데, 이 방식은 명령어를 하나씩 처리하는 방식으로 한 명령어가 끝나야 다음 명령어를 처리하므로 명령어를 쪼개서 한번에 여러개를 동시에 처리하는 파이프라이닝 방식에 비해서 비효율적이다. 파이프라이닝 방식을 적용하기 위해서는 명령어 사이의 데이터 흐름을 실시간으로 분석해야 하는데 명령어가 복잡하면 이 분석에 사용되는 하드웨어가 너무 복잡해져서 설계 비용이 증가하고 회로의 속도가 떨어지기 때문에 CISC에서는 폭넓게 적용하기가 매우 어렵다. 이 때문에 성능 향상이 나중에 나온 RISC에 따라잡히게 되면서 현재는 도태되었고 결국 100% 온전한 의미의 CISC 프로세서는 현재 시장에서 찾아볼 수 없다
x86 및 그 확장판 x86-64가 CISC를 채택하고 있는 대표적인 아키텍처이다. 하지만, 그것은 옛날 기술의 기준이지 현재의 x86 CPU는 내부적으로 RISC로 동작하면서 CISC 명령을 에뮬레이션하는 형태를 취하고 있기 때문에 CISC 아키텍처가 아직까지 살아남아 있다고 주장하기는 어렵다. 즉 CISC는 RISC와 섞여 혼종처럼 남아있는 상태라, 순수한 CISC는 현재 찾아볼 수 없다.
2.1. 장점
- 작지만 고밀도의 코드를 사용
- 생산성이 높다(마이크로코드 작성이 쉽다)
- 호환 명령어
[2]
이 덕분에 사실상 반쯤 추상화된 인스트럭션을 어떻게 해석하고 재 배치하는지에 따라 성능의 차이를 보여줘 오래된 코드들 또한 새로운 프로세서에서 성능상 이점을 주게 되는것에 비해 RISC와 같이 프로세서 파이프라인을 감안해 코드를 만들어 줘야 하는 RISC계열 프로세서의 경우 프로그래머와 컴파일러의 중요성이 높아지게 된다. 이 문제가 극대화된 프로세서가 VLIW.
2.2. 단점
- 구조가 복잡해 프로세서 설계가 힘들다.
- 파이프라이닝 구현이 매우 어렵다.
- 디코더가 비대해짐
다만 현대적인 CISC 프로세서들은 디코더에 가해지는 부하를 줄이는 uOP 캐시가 도입되고 성능에 있어 분기 예측, 비순차적 실행과 같은 설계들이 도입되고 있어 무작정 디코더가 CISC의 발목을 잡는다는 표현은 과거와 달리 항상 유효하다고 보기는 어렵다. 실제로 디코더가 작은 RISC나 RISC보다도 디코더가 더 작은 VLIW 계열이 90년대 한창 유행했으나 RISC는 아직도 CISC를 완전히 밀어내지 못했고 인텔은 2010년대 말 VLIW 계열 CPU인 인텔 아이태니엄 시리즈를 단종시킨다. 이런식으로 현대 x86프로세서와 같은 RISC화 된 CISC의 경우 인스트럭션 디코더가 사용하는 전력은 전체의 5%도 되지 않으며[3] OpCache의 Hitrate 가 떨어져 디코더가 다시 동작하는 상황에서도 3% 에서 10%로 증가하는것에 불과하며 나머지는 L1, L2 와 같은 인스트럭션 캐시와 순수 연산부분이 프로세서 소비전력의 90%이상을 차지한다. [4]
- 특정 환경에서 RISC보다 비효율적
- 기술의 발전으로 의미를 잃은 장점들
3. CISC 방식을 사용한 CPU들
4. 관련 문서
[1] 그 예시로 어떤 두 값을 비교 후 비교 결과에 따라 다른 값을 저장해야 할 때 CISC인 x86은 CMPXCHG 명령어 하나로 Lock, Load, Compare, Store 작업이 한번에 끝나고 Register operends 에 따라 비교 대상의 크기를 지정할 필요가 없지만 RISC 프로세서들의 경우 최소 4단계의 오퍼레이션이 필요하고 비교 대상의 레지스터에 따라 모든 구현을 직접 해야한다. Linux arm/include/asm/cmpxchg.h[2] 예를 들어 CISC계열인 x86의 명령어를 예로 들면 {{0x8c6131}} 명령은 16비트, 32비트, 64비트 모두 "
mov word ptr [(bx+di), (ecx), (rcx) + 0x31], fs
"로 레지스터 크기만 달라지고 동작이 동일하다.[3] uOP 캐시는 CISC 명령어의 주소에 디코드된 uOP들을 대응시키는 구조의 캐시인데, 특수 목적용 프로그램이 아닌 이상 대부분의 프로그램은 SIMD 벡터를 제외하면 mov
, lea
, push
, pop
같은 Load/Store I/O, sub
, add
, mul
, div
와 같은 정수/실수연산과 shr
, shl
과 같은 시프트연산과 and
, or
, xor
, cmp
, jz
, jnz
, je
, jne
같은 비교/분기 명령어 등 1-2개의 RISC식 uOp에 대응되는 명령어가 대부분을 차지하고, 대부분의 시간동안 특정한 루프를 반복하므로 (=자주 쓰이는 코드는 한정적) uOP 캐시의 적중률이 높은 편이다. 레이턴시가 길고 3개 이상의 동작을 해 uOP 캐시를 이용하기 어려운 복잡한 명령어는 AMD64로 넘어오면서 대부분 제거되어 SHLD/SHRD
, BSF/BSR
4개 명령어와 일부 특수 명령어 정도밖에 남지 않았다.[4] Empirical Study of Power Consumption of x86-64 Instruction Decoder[5] (xor eax, eax
), (mov eax, 0
), (sub eax, eax
), (and eax, 0
) 등등 모두 같은 역할을 하지만 모두 기계어의 길이가 다르다. (xor eax, eax
)는 (0x31 0xC0
)로 2바이트 명령어지만 (and eax, 0
)는 (0x83, 0xE0, 0x00
)으로 3바이트, (mov eax, 0
)은 (0xbb, 0x00, 0x00, 0x00, 0x00
)으로 4바이트 명령어다.[6] IBM의 메인프레임 컴퓨터에 사용되는 아키텍처로, 최신 하드웨어는 2021년에 발표된 Telum이다.