The Instruction Set : a Critical Interface
유저들은 하드웨어가 이해할 수 있는 언어를 사용해서 작업을 지시하게된다.
이 언어에 대해서 생각해보자.
Functions of Instruction Set
모든 프로세서는 최소한 아래의 기본 기능들은 수행할 수 있어야 한다.
- 산술 논리 연산
- 메모리와 데이터를 주고받는것 ( load / store )
- 조건부 분기(Conditional Branches)
- 조건을 결정하는 방법이 필요하다.
- 조건이 충족된다면 분기할 대상의 메모리 주소가 필요하다. 충족되지 않는다면 다음 Instruction으로 이동한다.
- 점프 또는 서브루틴 연결에 대한 프로시저 호출(Procedure call)에 관한 명령어가 있어야 한다.
- return address 가 있어야 다시 돌아올 수 있기때문에 프로시저 호출은 return address를 갖고있어야 한다
- 분기(branch)를 위해 넓은 범위의 타겟 메모리 주소가 필요하다.
추가기능
- 데이터를 레지스터 간, 입출력장치, 협력 프로세서( co-processor )로 이동한다.
- co-processor : floating point unit, memory management unit
- 예외와 인터럽트를 수행하기위한 명령어를 별도로 둘 수 있다.
Instruction Sets Classification
프로그램은 프로세서에서 실행이 되는데, 그때 필요한 값들은 레지스터, 메모리를 통해 프로세서로 오거나, 그 결과가 저장이 된다.
그때 그들 값에 따라 명령어를 통해 동작을 취하게 된다.
추상적 데이터타입
- Objects = Registers & Memory
- Operations = Instructions
- C code : a = b + c
- MIPS 'code' : add a, b, c
Operand(피연산자) vs Register
명령어는 위에 나왔던것처럼 기본적인 기능들은 지원해야하고, 그때 연산에 필요한 값을 Operand라고 한다.
그 값은 레지스터로 들어가게되고, 레지스터 안에 있는 값에 대해서 연산이 이루어진다.
Classifying Instruction Sets ( 명령어 집합 분류 )
- Machine : number/kind of registers
- 0 ( stack machine ) / 1 ( accumulator machine ) / small (2-6) / general registers (e.g. 16, 32 or more)
- # of addresses per instruction
- 0 ( stack machine ) //주소부 없음
- 1 ( accumulator machine ) //주소부가 1개
- 2 ( general registers ) //주소부가 2개
- 3 ( general registers ) //주소부가 3개
Instruction Set Architecture ( ISA )
ISA : 우리가 허용할 수 있는 명령어들을 정의한다. 정의되지 않은 명령어들은 처리할 수 없다.
결국 사용자 인터페이스를 통해 작업 지시를 하게 되면, 소프트웨어 계층을 거쳐 cpu에서 처리되는데 이때 필요한 값들은 system memory로부터 읽어오거나 network로부터 다운받아오게된다.
어떤 작업이던 사용자가 요청한 작업을 처리할 수 있는 명령어들을 갖고 있어야한다.
그리고 그 내역은 1과 0의 형태로 표현.처리 될것이다.
Goal of ISA Design
사용자들이 사용하는 어플리케이션 및 컴파일러로부터 생기는 제약조건을 만족시키면서 고성능 및 저비용을 충족시키는것.
Brif Historical Perspective on ISAs
- ISA 정의
- 시스템의 상태 (레지스터, 메모리, 프로그램 카운터)
- CPU가 실행할 수 있는 명령어
- 위와같은 명령어들이 시스템 상태에 미치는 영향/효과
<더하기 프로세스>
PC(Program Counter) : 메모리 내부의 가리키는 위치에 있는 내용을 읽어와서 레지스터에 넣는다.
이후 레지스터에 저장된 값을 가져와 CPU 가산기에서 더한 후, 그 결과를 레지스터에 넣는다.
이후 그 값을 메모리로 보낸다.
- 범용 레지스터
- 목적을 위해 레지스터를 사용하는 형태가 주류가 됨
- e.g. MIPS, ARM, x86
조금 더 세분화를 해보자.
- Register-memory architectures
- 연산에 필요한 값 중 하나의 피연산자(operand)는 메모리 안에 있다. (e.g. accumulators)
- E.g. x86 프로세서, 모토로라 68000
- Register-register architectures (aka load-store architectures)
- 모든 피연산자가 레지스터 안에 있어야 한다.
- E.g. MIPS, ARM
- 피연산자들은 메모리로부터 load를 통해 레지스터로 들어오고, 연산 결과는 store을 통해 메모리로 저장이 된다.
Memory Addressing Mode
ISA를 설계할 때 구체적으로 생각해야될것들이 꽤 있을것이다.
- 메모리 접근은 어떻게 할까...?
- 연산을 하는데 필요한 값이 레지스터 몇번에 들어있는지 어떻게 알까..?
- 실제 프로그램을 분석을 해봤더니 연산에 필요한 값의 데이터 사이즈가 word 크기보다 작은 상수값이 많이 사용된다면..? 어떻게 할까?
- ....
즉 ISA를 설계할 때 고려해야하는 design 이슈에 대해 논해보도록 하겠다.
Memorry Addressing = 주소 지정 인데, 이것이 물리적으로 어떻게 진행될까?
- 만약 k-bit의 주소가 있다면, k-bit로 지정할 수 있는 주소 공간의 크기는 $2^k$이다.
- 각각의 memory transfer는 하나의 $n$ bits word 이다.
- 기본적으로 메모리 주소는 byte 단위로 주소 지정이 가능한데, 명령어에 따라서 달라질 수 있다.
메모리 주소와 그 주소의 위치를 찾아 data를 가져오는 흐름 ( 중요 )
- 프로세스에서 메모리에 접근하기 위해 k-bit의 주소를 보낸다. (k-bit address bus) / 받는쪽 메모리는 $2^k$크기의 주소지정이 가능한 범위가 된다.
- 해당되는 위치의 n-bit크기의 data를 읽어서 가져온다. (n-bit data bus)
- 이때 Control lines을 통해 read인지 write인지.. 아니면 다른것인지 조정을 하게 된다.
Addressing Mode ( 주소지정방식 )
연산에 필요한 피연산자(operands)가 어디에 있는지 명시하는 방식
Operations in Instructions Set ( 작업에 사용되는 명령어 집합 )
- Data Movement (데이터 이동)
- load (from memory), store (to memory)
- memory-to-memory move
- register-to-register move
- input (from I/O device)
- output (to I/O device)
- push, pop (to/from stack)
- Arithmetic (산술 연산)
- integer (binary + decimal) or FP
- add, subtract, multiply, divide
- Shift (쉬프트 연산)
- shift left/right, rotate left/right
- Logical (논리 연산)
- not, and, or, set, clear
- Control flow (흐름 제어)
- Jump (unconditional), Branch (conditional)
- Jump (unconditional), Branch (conditional)
- Subroutine Linkage (서브루틴 연결)
- call, return
- Interrupt (인터럽트)
- trap, return
- Synchronization (동기화)
- test & set (atomic r-m-w)
- String
- search, move, compare
- Graphics
- pixel and vertex operations,
- compression/decompression
Instruction Usage ( 명령어 사용빈도 )
위 표를 보면 load(메모리로부터 읽어오는 동작), conditional branch(조건분기), compare(값 비교), store(메모리에 저장) 이 넷이 전체의 70%를 차지하고있다.
- load, store 두가지가 34%를 차지하고있는것으로 보아, 생각보다 아주 간단한 명령어의 사용 빈도가 높다.
- 96%를 제외하고 나머지 명령어들은 빈도수가 매우 낮다.
따라서..
Amdahl's law ( 암달의 법칙 )
자주 사용되는 명령어들을 빠르게 만들면, 공통적으로 많이 사용되는 케이스들이 빨라지므로 전체 프로그램의 실행시간이 짧아져 성능이 향상된다!
Instruction Formats : Length, Operation ( 명령어 형식 : 길이, 동작)
명령어도 1과 0의 조합으로 표현되고 처리된다.
명령어의 길이를 생각해보자.
명령어를 고정형으로 길게 만들어 동작을 나타냄과 동시에 그때 필요한 값을 포함하거나 위치를 알려주는 정보를 넣는 경우가 있을것이고
또는, 동작의 복잡성에 따라 명령어의 길이를 가변적으로 바꾸고 싶어할수도 있을것이다.
명령어 포멧 중 길이는 크게 세가지로 나눌 수 있다.
- 1. Variable-length instructions ( 가변 길이 명령어 )
- 80x86 : 1 ~ 17 bytes, Digital VAX : 1 ~ 54 bytes
- 장점 - 복잡하지만 유연하고 좀더 작게(최적화측면에서) 명령어를 만들 수 있다. ( e.g. 복잡한 연산은 길게 만들고, 단순하거나 자주 사용되는 연산은 짧게 만들 수 있다.)
- 단점 - 명령어의 길이가 가변적이라면, 한번에 읽어오기 힘든 길이의 경우가 있을 수 있으므로 여러 단계를 거쳐 가져오고, 여러 단계를 거쳐 디코딩(의미 부여)을 해야한다.
- 2. Fixed - length instructions ( 고정 길이 명령어 )
- 대부분의 RISC ( Reduced Instruction Set Computers ) 에서 사용한다.
- MIPS, PowerPC는 명령어가 4bytes의 길이를 갖는다.
- 메모리로부터 읽어올때 쉽게 읽어올 수 있다. //word 크기로 4bytes 잡고 읽어오면 쉽다. 크기가 고정되어있으므로 의미부여도 쉽다.
- 중첩처리와 병렬처리를 단순하게 할 수 있다.
- 3. Hybrid instructions ( 하이브리드( 가변 + 고정 ) 명령어 )
- 가변 방식과 고정 방식을 섞은 명령어.
그렇다면, 명령어 길이 뿐만 아니라 서로 다른 동작을 명령어 1과 0으로 이루어진 길이 상에 어떻게 표현 할까??
- Opcode (operation code)
- 원하는 동작을 구체적으로 나타내기 위한 unique code
- 연산에 필요한 값들의 type과 size
- Character (8 bits), half-word (eg: 16 bits), word (eg: 32 bits), single-precision floating point (eg: 1 word), double-precision floating point (eg: 2 words).
Encoding the Instruction Set ( 명령어 부호화 )
프로세서에서 실행할 수 있도록 명령어를 binary 값으로 만드는것.
가변 방식
- 맨 앞 : Operation( 동작 )과 동작에 필요한 피연산자( operand )의 갯수
- 그 다음 : 주소부(1), 값(1), 주소부(2), 값 (2), ....
고정 방식
- 맨 앞 : 동작을 나타냄
- 그 다음 : 값(1), 값(2), ...
하이브리드 방식
RISC vs. CISC
- Complex Instruction Set Computer (CISC) : x86-32(IA32)
- 상대적으로 복잡한 명령어 집합을 가짐
- 명령어 갯수가 많다. ( 1000개 이상 )
- 명령어가 가변적인 길이를 가진다 ( 1 to 15 bytes each )
- 하나의 명령어가 복잡한 동작을 수행하는 경우가 있다.
- 주소 지정 방식이 종류가 많다 (10s of addressing modes)
- 서버/데스크톱에 많이 사용됨.
- Reduced Instruction Set Computer (RISC) : MIPS, ARM
- 명령어의 갯수가 적다 ( 약 200개정도 )
- 명령어의 길이가 똑같다
- 3가지 타입을 가진다
- 작고 심플해서 하드웨어 시스템을 구축하고 최적하기 용이하다.
- 모든 연산에 필요한 연산자가 레지스터 안에 있다 (중요)
- 에너지 효율 중시, 임베디드 시스템, 휴대용 디바이스에 사용됨.
RISC는 단순한 하드웨어가 더 빨리 실행된다는 원칙(예: MIPS)에 기반한 아키텍처 설계 개념이다.
작고 일반적인 명령 집합을 사용하여 좋은 성능을 뽑아낸다.
Mainstream ISAs
RISC-V : 오픈소스
Summary
- 동일한 명령어 셋 아키텍쳐를 서로 다른 형태로 구현이 가능하다
- 명령어 셋 아키텍쳐는 Stack, Accumulator, General Purpose Register(GPR. 범용 레지스터)
- 대부분 오늘날 시스템은 범용 레지스터를 베이스로 사용하고 있다.
'ETC > CS' 카테고리의 다른 글
[컴퓨터구조] ch.2-3 MIPS (0) | 2020.10.25 |
---|---|
[컴퓨터구조] ch.2-2 산술 동작 (0) | 2020.10.24 |
[컴퓨터구조] Ch.1 컴퓨터 추상화와 기술 - Computer Abstractions and Technology (0) | 2020.10.21 |
Lambert's cosine Law (0) | 2020.06.08 |
퐁 모델 (phong model) (0) | 2020.06.07 |
댓글