ch04 cpu의 작동원리
학습목표
- ALU와 제어장치 설명
- 레지스터의 종류와 역할 설명
- 명령어 사이클 이해
- 인터럽트의 개념을 이해
04-1 ALU와 제어장치
cpu를 구성하는 내부 장치들
- 산술논리연산장치 == arithmetic and logical unit == ALU
- 연산을 수행하는 장치!
- 제어장치 == control unit == CU
- 명령어를 해석하는 장치!
- 레지스터 == register
- 상태를 담을때 필요한 장치!
ALU
계산 장치이다. 직접적으로 계산을 처리하는 핵심 장치이다.
이런 계산 장치에 input 유형과 output 유형이 있다.
[input]
- 제어신호: 제어장치가 명령어를 해석. 오퍼레이션 코드와 대응. 산술 or 논리 등 ALU 전용담당 제어신호들이 있음.
- 피연산자: 데이터. 레지스터 or 메모리로부터 받음. 명령어에서 오퍼랜드에 대응되는 개념인데, 이것 또한 제어장치가 적절하게 제어명령신호를 각 기관에 보내어 올바른 타이밍에 ALU에게 데이터가 도달되게 함.
[output]
- 결과값: 계산 결과. 레지스터 or 메모리에 저장
- 플래그: 계산 직후 특이사항에 따라 각각의 플래그 레지스터를 변화시킴 즉 메모리같이 계속해서 프로세스를 위해 저장해두고 있는게 아니라. 그때 그 순간의 상황을 데이터만으로 표현하기엔 부족하기에 일시적으로 빠르게 write/read 되는 레지스터임. 특정 연산 시에 주요한 플래그 레지스터의 결과값에 따라 저장된 결과를 어떻게 해석할지를 판별함.
플래그 구체적인 예시 -> 얘네들은 전부 상태 레지스터라는 곳에 있는 한 공간 비트
상태 레지스터 status register == 플래그 레지스터 flag register == 조건 코드 레지스터 condition code register CCR
다 같은 말이다. 그 레지스터 안에 있는 대표적인 플래그 종류들이다. 레지스터의 1비트 공간을 떡하니 차지하고 해당 비트값이 바뀐걸로 상태값을 표현한다.
플래그 종류 | 의미 | 사용예시 |
---|---|---|
부호 플래그 sign flag N/S | 1이면 음수 0이면 양수 | if (A > B) goto label; 와 같은 조건문에서 A-B 연산 결과 부호 플래그 사용 |
제로 플래그 zero flag Z | 1이면 0 true 0이면 0 false | while (A != 0) A = A - 1; 와 같은 반복문에서 A가 판별시 제로 플래그 사용 |
캐리 플래그 carry flag C | 1이면 올림 및 빌림 발생 0이면 일어나지 않았음 | unsigned 2바이트 정수를 더할 때, 상위 바이트로 캐리가 발생하면 CF가 설정 |
오버플로우 플래그 overflow flag V/O/W | 1이면 오버플로우 발생 0이면 일어나지 않았음 | signed 8비트 정수에 127을 더하면 오버플로가 발생하여 OF가 설정 |
인터럽트 플래그 interupt flag I/E | 1이면 인터럽트가 가능함. 0이면 불가능함 | 인터럽트 처리: 특정 이벤트가 발생했을 때 프로그램의 실행을 중단하고 인터럽트 처리 루틴을 실행합니다. 별 중요하지 않은 명령어 처리시에 1이 되어 항시 인터럽트를 받아들일 준비를 하고 있음. 반면 운영체제 명령과 같이 끊기면 안되고 길게 가져가야되는 명령에 진입시에는 일시적으로 0으로 바꾼 상태를 유지하여 인터럽트를 차단하여 온전히 CPU자원을 씀. |
슈퍼바이저 플래그 supervisor flag S | 1이면 커널모드로 실행중임 0이면 사용자모드임. | 모드 전환: 커널 모드와 사용자 모드 간의 전환을 제어합니다. 권한 관리: 커널 모드에서는 시스템의 모든 자원에 접근할 수 있는 반면, 사용자 모드에서는 제한된 권한만 가지므로, 보안을 위해 사용됩니다. 커널모드를 사용하여 나 중요한 데이터에 접근하고 있어요~라고 알려주는 플래그이다. 해당 플래그는 인터럽트 플래그와 밀접하게 작동하기도함. 이 역시 명령어를 해석할때 s 값을 바꿀지 말지를 결정함. |
자주바뀌는 결과 관련 플래그: 산술, 제로, 캐리, 오버플로우
여러 연산을 진행하는 동안 안바뀌는 모드 관련 플래그: 인터럽트, 슈퍼바이저
제어장치 control unit CU
CU는 컨트롤 타워야. 지휘자야. 커멘드 센터야. 명령어를 해석하여 각 장치에 제어신호를 보낸다고 했다. output은 제어신호이고 input은 명령어다. 이게 전부는 아니겠지…
[input]
- 쿨럭
쿨럭은 매우 중요한 개념. CPU의 성능에따라 일정한 속도를 내도록 되어 있는데 그 일정한 명령어 수행 주기가 쿨럭이다. 1쿨럭만에 끝나는 명령도 있고, 200쿨럭이 필요한 명령도 있을 수 있다. 아무튼 이런 쿨럭단위로 움직인다.
이때! CU는 현재 쿨럭, 명령어에 필요한 쿨럭, 각장치들이 소모하는 쿨럭, 해당 장치들이 언제어 떤 명령을 수행해야되는지 즉 “타이밍 동기화” 를 아주 일사분란하게 처리하기 위해선 반드시 적을 알고 나를 아는 쿨럭마스터가 되어야한다.
그래서 CU는 쿨럭을 항시 입력받고 스스로 쿨럭을 이용하여 명령어에 적절한 타이밍동기화 해석까지 이루어 낸다.
쿨럭 인풋! 필수
- 명령어
명령어를 해석하여 제어신호를 보내는 중추인데 당연히 받아들여야지. 명령어를 쫙 해석하여 “명령어 레지스터”에 미리 명령어를 저장해 놨다가. 올바른 쿨럭에 해당 명령어를 받아들이게 된다.
- 플래그
플래그도 받아들인다. 명령어 해석에 있어 플래그상태만으로 명령어의 동작을 결정하기도 하고 오퍼랜드와 플래그의 조합으로 명령어를 해석하기도 한다.
- 제어신호
제어신호를 받기도 한다. 주로 CPU외부 장치의 제어신호를 받아들여 해당신호를 어떻게 처리할지 또 제어신호로서 다룬다.
[output]
유일무이 제어신호
제어장치는 제어신호도 받고, 명령어도 받고, 플래그도 받고, 쿨럭도 체크하는데 이 모든건 적절한 제어신호를 보내기 위함이다. CPU내부인 ALU, 레지스터에 보내는 경우도 있지만, 시스템 버스의 제어 버스를 타고 들어가서 CPU 외부 장치에도 적절한 제어신호를 보내는 역할을 하는건 CU의 역할
마무리 키워드
- ALU
산술논리연산장치 제어신호가 해석한대로 계산을 수행하는 계산머신 결과값을 리턴하고, 상태레지스터의 플래그 값을 연산결과에따라 적절히 바꾼다.
- 플래그
현재 상태를 표현하기위한 개념. 상태레지스터의 비트값으로 표현됨. 부호, 제로, 캐리, 오버플로우, 인터럽트, 슈퍼바이저 등의 상태 표현이 있음.
- 제어장치
CU. 컨트롤타워 역할. 명령어를 해석하여 적절한 타이밍에 올바른 동작이 하도록 제어신호를 뿌려대는 역할. 그러기 위해서 명령어, 쿨럭, 플래그, 제어신호 등을 받아서 해석하고, 올바른 제어신호를 리턴한다. 각 장치에
- 제어신호
각 장치에 맞는 제어신호들이 존재함. 크게 타 장치가 제어장치에 보내는 신호와 제어장치가 다른 장치에 보내는 신호로 나누어지고, 더 나아가 제어장치가 cpu 내부에 보내는 내부신호, cpu 외부에 보내는 외부신호로도 나눌 수 있다.
확인문제
더보기
1. - 5
2. 4, ?
3. 1. 플래그 레지스터 2. 명령어 레지스터 3. 제어 버스
4. 4
틀림
1번 정답: -3
부호 플래그가 음수이므로 해당 결과값을 곧이 곧대로 해석하여 -1을 붙이는게 아니라 보수로 표현된 음수라고 까지 보고 101 -> - 011 해서 -3으로 해석해야된다고 한다.
04-2 레지스터
반드시 알아야할 레지스터 리스트
- 프로그램 카운터: program counter == PC
- 명령어 레지스터: instruction register == IR
- 메모리 주소 레지스터: memory address register == MAR
- 메모리 버퍼 레지스터: memory buffer register == MBR
- 플래그 레지스터: flag register
- 범용 레지스터: general purpose register
- 스택 포인터: stack pointer
- 베이스 레지스터: base register
레지스터 동작 원리보단 명칭과 목적에 중점을 둔 학습 권장
프로그램 카운터
정의
다음에 실행할 명령어의 메모리 주소를 저장하는 레지스터.
기능
순차적 실행: PC의 명령어가 인출(fetch)될때 마다 PC의 주소는 갱신된다.(명령어가 끝날 때까지 기다리지 않는다!!) 어떻게 갱신되냐면, PC에 저장된 명령어의 길이만큼 +한 주소가 바로 다음 명령어 주소로 되어있다.(프로그래밍적 특징임)
분기(Branch) 명령: 조건 분기, 무조건 분기, 서브루틴 호출 등 의 명령어라면 순차적인 실행의 계산법과는 다른 계산법이 PC에 적용되어 진다.
인터럽트 처리: 인터럽트 발생 시 PC의 현재 값은 스택에 저장되고, 인터럽트의 루틴 주소로 PC는 바뀐다. 인터럽트 처리 후딱 끝내자마자 다시 PC값을 복원하여 원래 흐름을 복귀한다. 이 과정은 복잡해보이지만, 거진 빛의 속도
고급 내용
명령어 프리패치(Instruction prefetch): 현대 CPU는 무식하지 않다. 미리 여러 개의 명령어를 인출해 두어 속도가 향상된다.
파이프라이닝: 명령어인출이 끝났다면 pc의 역할은 끝. PC는 인출하기위한 명령어를 제공하는 역할을 한다. 단, 이건 순차적으로 깔끔하게 끝날때는 고려하지 않아도 되는 부분이 있지만, 만일… 분기나 점프 명령어라면, 명령어 끝나는 시점에 이전 명령어에 대한 계산값이 필요하다. 그게 어디서 처리되냐? 현대 CPU는 PCU라는 pipeline control unit 개념이 존재하기에 여기서 분기한 명령어 주소는 어디라는것을 알려준다…. 예외처리의 경우엔 EPC exception program counter가 그 역할을 맡는다…
슈퍼스칼라(Superscalar): 여러개의 PC 사용!
명령어 레지스터
정의
현재 실행 중인 명령어를 저장하는 레지스터
기능
명령어 저장: 인출된 명령어는 MBR을 거쳐서 IR에 저장됨
명령어 해독: 제어장치가 해독을 시도할때 IR의 명령어를 해독한다.
고급 내용
마이크로프로그래밍: 명령어를 저장한 IR을 해독->실행할때 더 작은 단위로 분해하여 실행하는 방식 즉. 쪼개는게 가능한 명령어
메모리 주소 레지스터
정의
메모리 주소의 개념은 전부 MAR에 저장되고 거쳐감.
기능
메모리 주소의 전달: CPU가 메모리에 데이터 읽기 쓰기 접근할때 MAR에 저장한뒤 그걸 주소버스를 통해 접근함.
고급 내용
가상메모리(VM. virtual memory): 어려워서 생략
메모리 버퍼 레지스터
정의
메모리에서 읽어온 데이터 및 써야할 데이터 들을 저장하고 거치는 공간
기능
데이터 전송 중개: MAR을 통해 가져온 데이터는 일단 MBR에 넣음. 만약에!! 주소면? 어쩔건데? 명령어 아니면? 어쩔건데? 인출은 말그대로 인출만함. 뭔지 몰라. 그냥 정확히 가져오고 다음 주소 가리킬 뿐이야. 가져왔더니 간접주소지정으로 복잡하네? 라고 판단하는건 다음단계인 디코드 과정 해석과정을 거쳐야 알수 있음. 해석을 하는 주체는 CU이다. 즉 명령어든지 뭐 주소든지 간에 일단 IR에는 들어가는거임. 그러고나서 별반 연산 없이 다음 주소로 이동! 이라는 해석을 하는건 CU가 판단
위의 4가지를 활용한 실행 흐름 개요 설명
- 프로그램 로딩
프로그램이 로딩 되자마자 PC에 다음 명령어의 주소가 저장된다!
- 명령어 인출(패치)
앞으로 계속 반복될 첫 번째 동작이다. PC의 주소값 -> MAR로 복사 -> 주소버스를 이용한 메모리 주소 접근 -> 데이터 버스를 이용하여 주소안의 내용물을 MBR로 가져옴-> MBR에서 IR로 복사 -> PC는 다음 주소로 갱신(이때 명령어의 오퍼레이션 코드의 일부 비트만 확인하고 분기명령인지, 점프명령인지 순차명령인지 등을 예단하여 PC 주소를 갱신하게 된다!!)
- 명령어 해독(디코드)
IR을 본격적으로 CU가 해석하게 된다. 오퍼레이션 분석, 오퍼랜드 분석을 하게 된다.
- 오퍼랜드 패치
만일 오퍼랜드 분석시에 인출해야될 데이터가 더 있어 막 그럼 수행하게 되는 단계이다.
즉시 값: 데이터가 명령어 오퍼랜드에 포함됨. 이러면 IR에서 직접 추출 하여 놀고있는 레지스터에(실제론 뭐 있겠지.. 그만 딥하게 들어가..) 데이터 저장해두겠지.
레지스터: 오퍼랜드가 레지스터 주소를 가리킴. 아하 해당 레지스터 주소로 가서 연산에 참여할 데이터 가져오면 되겠네
메모리 주소: 위에 명령어 인출 단계에서 수행한 MAR -> 주소버스 -> 메모리 -> 데이터 버스 -> MBR 단계를 전부 수행하겠지.
- 명령어 실행
ALU가 드디어 이제 모습을 드러내어 레지스터로 부터 오퍼랜드 데이터 싹 받아와서 연산을 할거다 -> 결과 저장 -> MBR에 저장 or 다른 레지스터에 저장 등을 하겠지. -> ALU의 역할 끝. 다시 CU가 제어신호를 보내어 버스타고 메모리 보내
와우 빡세다
범용 레지스터
역시 MAR이나 MBR처럼 목적과 책임이 명확한 레지스터말고 무책임하게 막 임시 데이터 저장공간용으로 레지스터가 있을 줄 알았어 딱 이 놈임.
플래그 레지스터
04-1에서 다루고 넘어갔다.
스택 포인터
정의
스택의 최상단 주소를 가리킴. stack pointer. SP
기능
푸시: 하나씩 쌓는거. 이때 SP값은 감소시키고 해당 주소에 데이터 저장함. -> 거꾸로 생겨 먹었다고 보면 된다. 암튼 스택의 최대 길이가 1024면 최초 주소값이 1024로 시작한다고 보면 된다!! 이건 외워야지 뭘 0->max가 아니라. max위치에서 0까지 차오른다
팝: 푸쉬 반대
베이스 레지스터
메모리 주소를 계산할때 기준이 되는 값을 저장하는 레지스터
명령어는 현재 프로그램이 RAM 어느 부분에 위치하고 어디가 비어있고 등을 일일히 라이브하게 계산하여 도출되어 다시 쓰여지고 그러지 않는다!! 그저 offset을 기준으로 +0부터 +n까지 가든 a=true면 +120 a==false면 -320 이든 암튼 offset을 기준으로 항상 프로시저 논리를 만족한다!!
주소지정방식1: 스택 주소 지정 방식
정리하자면!! 프로그램의 스택 영역은 따로 존재하며 해당 스택 영역에 읽고 쓰기가 진행될때에는 항상 스택 포인터와 밀접하게 연관되어 일어난다. 스택포인터 -> MAR 이런식
주소지정방식2: 변위 주소 지정 방식
더 간단하게! 명령어를 읽어와. 해당 명령어를 해석해. 이놈 가만보니 오퍼레이션 코드는 레지스터 주소값과 오퍼랜드 주소값을 합친게 필요한 다음 메모리 주소라는 걸 알려주는 명령어네? 이런 방식들이 전부 변위 주소 지정 방식이야.
변위: 위치를 바꾸는 일. 그때 그 일을 하기 위해 필요한 방향과 크기 개념
어디를 기준으로 위치를 바꿀거냐~ 그래서 변위 주소 지정방식이고.
그 어디냐에 따라서 또 여러 지정방식으로 나뉜다!!
상대 주소 지정 방식: PC값 + 오퍼랜드 주소값 -> 변위!
베이스 레지스터 주조 지정 방식: 베이스 레지스터값(offset) + 오퍼랜드 주소값 -> 변위!!
마무리 키워드
프로그램 카운터
다음 실행할 명령어의 주소를 저장할 책임이 있는 레지스터
명령어 레지스터
CU가 실행할 명령어 그 자체를(데이터 타입~) 저장할 책임이 있는 레지스터
메모리 주소 레지스터
메모리 주소를 다루기 위해 주소버스와 직통하는 레지스터
메모리 버퍼 레지스터
메모리로부터 해석한 데이터를 다루는 레지스터
범용 레지스터
특별한 책임 없이 사용가능한 레지스터
플래그 레지스터
연산결과 상태 및 현재 모드 상태까지 표현하기 위한 레지스터
스택 포인터
항시 스택 최상단 주소를 가리키고 있는 레지스터
베이스 레지스터
프로그램의 offset 주소를 저장하고 있는 레지스터
확인문제(과제1)
더보기
1. 2100번이요
2. 1. 플래그 레지스터 2. 프로그램 카운터 3. 범용 레지스터 4. 명령어 레지스터
3. 6번지
4. 4번
04-3 명령어 사이클과 인터럽트
명령어 사이클: 명령어를 처리하는 정형화된 흐름. 1클럭만에 처리할지 13클럭만에 처리할지 알순 없지만, 주소를 참조해야할 수도 있고, MAR MBR을 수십법 왔다 갔다 할수도 있는데 하여간 명령어를 하나 읽어와서 제대로 실행되는거 까지가 한 사이클
인터럽트: 흐름이 끊기게 되는 원흉. 근데 필수. 의도적일 수도 의도는 아닐 수도 외부에의해 생길수도
명령어 사이클
명령어 사이클 참조 주소
명령 주기 - 위키백과, 우리 모두의 백과사전
[명령 주기 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 명령 실행 주기 도표 명령 주기(命令週期, 영어: instruction cycle, machine cycle)는 마이크로프로세서(CPU)가 메모리로부터 프로그램 된 한개의 기계어 명령어를 가져
ko.wikipedia.org](https://ko.wikipedia.org/wiki/%EB%AA%85%EB%A0%B9_%EC%A3%BC%EA%B8%B0)
정의: CPU가 명령어 하나를 수행하기 위해 필요한 일련의 과정
[간략화]
인출 사이클
CPU로 필요한 명령어를 성공적으로 가져와서 세팅하는 과정
간접 사이클
만일 오퍼랜드를 세팅하는데 있어 명령어만으로 끝나지않고 유효주소를 읽어와 데이터를 가져와야 할 경우 그것을 하는 과정
인터럽트 사이클
인터럽트를 통해 문제를 해결하고자 하는 과정
실행 사이클
명령코드와 오퍼랜드를 통한 적절한 명령 실행
인터럽트
정의: 방해하다. 원래 CPU가 해야될 흐름을 살짝 방해하고 필요한 일처리를 후딱 해치우고 오는 행위.
[왜 인터럽트가 필요한가?]
첫째, CPU의 속도는 월등히 빠르기에 하드웨어의 입력을 일일히 기다려줄 수 없다. 하지만 그럼에도 하드웨어 입력할때 바로바로 입력을 받아줬으면 좋겠다.
즉 압도적인 성능을 자랑하는 CPU님은 엄청난 피지컬을 자랑한다. 하지만 한 순간에 하나의 동작만 처리할 수 있는데, 이때 마냥 입력해주세요만을 대기하는게 아니라, 미친 속도로 왔다 갔다 하며 입력 출력 계산 까지 모든걸 초스피드로 순환하는 구조를 인터럽트라는 방식으로 처리해버린다. 속기사가 암만 2000타 속도로 때려봐야 CPU의 1클럭 속도에 피도 못추리는 느린 속도이기때문에 짬짬이 시간내어 처리하는 방식이 하드웨어 인터럽트 처리 방식의 이유
둘째, 구동환경이 완벽하지 못할 수 있을때 잠깐 환경 맞추고 쥐도새도 모르게 처리해버리기 위해서 인터럽트를 작동시킨다.
만약 프로그램 명령어는 오류 따윈 없었으나, 상대주소 지정방식의 예에서 PC의 다음주소 3000만큼 더한 다음 주소에 접근하여 데이터를 가져와라고 했는데 얼래리 물리적으로 불가능할때, 폴트 인터럽트가 발동되고 해결가능하게 세팅을 한뒤에 다시 돌아와서 뭔일 있었냐는 듯이 스무스하게 정상작동 시킨다. 그러고 싶을때에도 인터럽트라는 시스템을 적극적으로 활용하여 부드러운 환경을 제공함.
셋째, 의도적으로 흐름을 멈추고 싶을때, 의도적으로 멈추고 뭔가 다른걸 해야하는 상황에도 적극적으로 활용
대표적으로 디버깅할때 발생한다. 트랩 인터럽트는 평상시 컴파일에서는 존재하지 않는 명령어이나, 디버거가 중단점을 가진채로 디버깅을 런하면, 중단점이 발생했을때 의도적으로 트랩 인터럽트가 발동하고, 필요한 관찰을 하게 된다. 다시 원래 상태로 돌리고 싶다면 탈출을 하게 될텐데 이때 중단점을 재실행하거나 그 이전으로 가는거 없이 즉 “중단점 명령어”의 재실행없이 기존에 원래 순서였던 하지만 디버거에 의해 다음순서가 되어버린 원래 명령어가 실행되게 된다. 이게 유명한 디버깅 트랩의 예시
넷째, 그냥 버그. 치명적 버그. CPU가 어차피 지금 명령어든 다음명령어든 동작을 못할수준이 되었을때 중단시키는 것. 어볼트가 있음.
[인터럽트의 종류]
하나. 동기인터럽트 = synchronous interrupt = 동시 인터럽트 = 실시간 인터럽트
왜? 동기? 명령어 사이클의 실행 직후 바로 발생하는 인터럽트라서 동시 실시간 동기 싱크로너스 이런 이름이 붙었다.
위에 폴트, 트랩, 어보트가 그 예시
둘. 비동기인터럽트 = asynchronus interrupt = 비실시간 인터럽트
왜 비동기? 위의 동기와 다르게 명령어랑은 무관하게 발생하는 이벤트성 인터럽트라 그렇다.
이런 이벤트는 외부 장치에 의해 일어남.
외부 장치에 의해 인터럽트 요청 신호가 발생.
CPU는 명령어 사이클 후 항시 명령어 인출 바로 직전에 인터럽트 요청을 항상 확인
이때 인터럽트 플래그가 온이면, 받아들일 수 있고, 오프면 못받아들이고 명령어를 그냥 수행.
[인터럽트의 수행]
첫째, 백업
인터럽트가 발생하면 PC에서 MAR로 가기 직전에 즉 인출전에 처리하는 하드웨어 인터럽트든, 명령어 실행 직후 발생한 동기 인터럽트든 간에, 제대로된 프로세스 수행을 위한 다음 PC값(돌아와야할 값. 하드웨어 인터럽트면 현재 PC값이고, 동기 인터럽트라면 어떤 인터럽트냐에 따라 조금 다를것.)을 스택에 저장함. 다른 레지스터들도 PC값 이후 순차적으로 스택에 쌓임. 이거에 대한 자세한건 결국 운영체제까지 가서…
둘째, 인터럽트 벡터 + 인터럽트 서비스 루틴
인터럽트 요청신호를 받으면 해석을 하여 어떤 인터럽트 서비스 루틴을 실행해야하는지를 파악함. 그 인터럽트 서비스 루틴을 가리키고 있는 주소가 인터럽트 벡터에 시작 주소가 저장되어 있고, 이 시작 주소가 PC에 세팅되어 마치 다음 명령어를 실행하듯 cpu를 정상 작동 시키면 서비스 루틴이 실행됨.
셋째, 복구
인터럽트 서비스루틴이 끝나면, 일반적으로는 서비스루틴안에 있는 명령어로 인해 스택의 정보를 참고하여 PC값과 레지스터값들을 복구하라는 명령어인 RETI로 인해 정상 복구됨. 깊은건 운영체제때.. 암튼 이후엔 문제가 해결되었으니 정상 작동하는 프로세스가 돌아가게됨.
확인문제
더보기
1. 4번은 반대 설명
2. 3번 막을 수 없는 인터럽트도 있다. 그걸 논 마스커블 인터럽트라고
3. 인터럽트 서비스 루틴
4. 2번
5. 3번 … 명령어가 아니라 프로그램이니까.. 이 설명이 맞는거 같다.
05-1 빠른 CPU를 위한 설계 기법
클럭
클럭 뜻. 단순히 시계 그자체가 클럭. 하지만 CPU에서 일반적으로 클럭은 클럭 신호
혹은 클럭 속도
정도로 사용된다.
클럭 신호
정체: 고주파 전기 펄스.
역할: 규칙적으로 0과 1을 전환. 여기서 이진코드로 이루어진 데이터들이 0과 1로 구성되어 있다고 해서 그녀석들과 착각 하면안됨. 클럭신호의 0과 1은 일정한 주기로 반복된다는 것이 중요. 동작 타이밍을 정의하는것. 지휘 역할. 트리거 역할. 동기화 역할(명령어 문법과 데이터 처리, 그 다음 데이터의 연속성 처리에서 무결성 확보)
어떻게 만드는가? : 석영압전 효과를 가지고 있음. 압력을 가하면 전류가 흐름. 그 반대로 전류를 흘리면 수축 팽창하며 일정한 진동수를 발산함. 이 진동수가 일정한걸 이용하여 프로그래밍의 동기화에 이용하는것이 지금 CPU들의 원리
처음부터 CPU에 활용된것은 아니고 이런 클럭신호를 이용하여 쿼츠 시계가 발명된것이 시초. 이후 일정한 주기가 필요한 GPS, 아날로그 TV 등 여러 일정 주기 생성자로 석영 압전효과가 많이 활용됨.
클럭 속도
위의 클럭 신호가 1초 동안 몇번을 진동하는지를 나타내는게 클럭 속도. 빠르면 빠를 수록 해당 CPU는 일정 전력 이상에서 명령어 처리를 할 수 있음을 의미. 하지만 무한정 높일 수 없는 이유는, 전력 소모가 많을 수록 발열이 기하 급수적으로 올라가서 일정 발열 이상에서는 저항이 높아져 전류 효율이 안나오고, 성능이 역행하게 됨. CPU의 성능은 결국 같은 전력을 소모할때 더 높은 클럭을 내는 기술에서 CPU 성능이 결정됨
클럭 속도는 일정하지 않다
클럭 신호가 주기적으로 진동한다는건 계속해서 전력을 소모한다는 뜻. 전력 소모를 줄이기 위해서는 저전력으로 클럭 속도가 내려가고, 고성능을 뽑기 위해서는 전력을 증가시켜 빠르게 진동하게 한다. 이를 언더클러킹
, 오버클러킹
이라고 함.
코어와 멀티코어 (과제3)
코어
앞서 공부했던 CPU에 관한 공부들이 사실 전부 코어에 대한 공부이다.
ALU + 제어장치 + 레지스터 + 버스
이 조합은 사실상 코어에 관련한 내용이다. CPU의 근본은 1코어 CPU이다. 하지만, 요즘 CPU는 거의 멀티 코어 CPU이다.
멀티코어
코어가 여러개인 CPU를 멀티코어 CPU라고 한다. 성능 향상의 방법으로, 진동수를 무지막지하게 늘리는 원코어 CPU보다 적절한 진동수의 코어를 여러개 가진 CPU가 성능향상에 더 효율적이기 때문
스레드와 멀티스레드 (과제3)
스레드
뜻 : 실행의 흐름 단위
종류 : 일반적으로 하드웨어 스레드
, 소프트웨어 스레드
로 구분함.
소프트웨어 스레드
CPU랑은 상관 없이, 프로그램이 실행되고 나서 동작할 흐름을 스레드를 생성하여 동시 작업시키는걸 의미함. 예를들어 배경음악 재생기 같은게 예시가 될 수 있다. 프로그램 시작하자마자, 사용자의 입력을 기다리면서 뭔가를 그려주는 렌더링이 돌아감과 동시에 배경음악파일을 해석하여 재생하는 녀석도 동시에 돌아간다. 이때 반드시 스레드로 돌려줘야지 사용자 입력과 배경 음악 재생 2가지가 돌아간다.
하드웨어 스레드
CPU의 관점에서 명령어를 처리하는게 코어라고 했다. 그런데 코어가 하나의 명령어가 아니라 마치 독림된 2개의 코어인거 마냥 실행의 단위를 2개 이상 처리할 수 있다. 이때 멀티코어 안의 멀티 코어라고 해서 멀티멀티코어가 아니라, 멀티 스레드라고 표현한다. 즉 한마디로, CPU안에 코어가 하나 있던 시절엔 굳이 코어 개념이 필요없었는데 멀티코어 때문에 생겨났고, 단일 스레드 개념일땐 필요없던게 이젠 멀티 스레드를 지원하기에 또 용어가 구별되어 생겨난거라고 볼 수 있음.
CPU를 프로세서라고 표현하고, 이를 각각 멀티코어 프로세서, 멀티스레드 프로세서라고 명명하기도 한다.
멀티스레드 프로세서를 위한 조건
코어 하나안에 마치 코어 2개인양 처리를 하기 위해서는 반드시 2개의 명령어를 저장하고 있을 레지스터들이 필요하다. 즉 명령어 하나를 처리하기 위한 최소 단위의 레지스터들을 묶어서 레지스터 셋이라고 표현한다면, 이러한 레지스터셋이 2개이상이면 멀티스레드 프로세서를 위한 조건을 만족한다. ALU나 제어장치는 스태이트리스 즉 상태를 저장하고 있을 필요가 없는 부품이다. 빠른속도로 왔다리 갔다리 해도 상관이 없다. 하지만 상태를 저장하고 있어야 되는 레지스터는 최소 조건을 만족하기위해 확실하게 구분된 여러개가 필요할 수 밖에 없는 이유이다.
확인 문제(과제2)
- 3번
- 4번
- 소프트웨어, 하드웨어
- 코어
05-2 명령어 병렬 처리 기법
명령어 파이프라인
정의: 명령어를 코어가 처리 가능한 양의 파이프라인에 넣고서 각 기관들이 쉴새없이 돌아가게 하여 동시에 여러 명령어를 처리하는 기법.
왜?: 코어는 하나의 명령어만 처리하기에는 너무 강력하다. 그래서 여러 명령어를 동시에 처리하는 것.
-> 그럼 성능좋은 CPU가 그냥 한 명령어 빠르게 처리하고 다음 명령어 순서대로 처리하면 되는거 아닌가?
-> 그렇지 않다. 코어는 ALU+ 제어장치 +레지스터 뿐만 아니라, 메모리와 하드디스크 및 기타 키보드 마우스 모니터라는 장치들도 이런 명령어에 복합적으로 관여할 수 있기에, 아무리 빠른 코어라고 해도 명령어를 한클럭 안에 해결하는 것은 불가능이다. 일부러 할 수 있어도 무결성을 위하여 클럭 단위로 쪼개서 작동한다.
-> 무결성을 위해 최소로 fetch -> decode -> execute -> memory access -> write back 의 과정은 거진 한클럭 단위로 작동하게 한다. 클럭의 장점을 활용하는 것. 성능이 좋아도 이렇게 나눠서 접근하면, 한 CPU가 일정 클럭동안 무엇을 하고 있을지 대강짐작이 된다.
-> 물론 성능이 좋으면 한클럭당 어마무시하게 많은 파이프라인을 돌릴 것이다. 하지만 그렇다고 해서 명령어를 한 클럭안에 해결하는 동작 같은건 위험성이 더 크다.
명령어 파이프라인의 위험(hazard)
그렇다고 클럭에 따라서 명령어를 수행하는 것이 안전한것과는 별개로 한 클럭 안에 여러 파이프라인을 수행하는 것이 마냥 안전한건 아니다.
데이터 위험
정의: 데이터 간에 의존성 때문에 발생. 마냥 파이프라인에 막 추가 할 수 없는 이유. 선행 명령어의 결과 데이터를 이용해야 되는 경우가 있을 수 있기 때문
해결 기법
- 컴파일러 최적화: 컴파일러가 최대한 이런 위험이 발생하지 않게끔 명령어 리오더링을 실시.
- 스텔링: stalling. 기다리기. 필요한 데이터가 준비되면 동작하게끔 명령어의 실행을 유보하는 형태를 취함
제어 위험
정의: 소스파일만 보면 분명 다음 차례 명령어들이 뭔지 정의되어 있는데, branch나 jump 명령어 때문에 다음 명령어가 뭔지 예측하기 힘들어서 파이프라이닝에 함부로 추가하기 어려운 경우
해결기법
- 분기 예측: 이번 명령어 다음에 올 명령어가 어떤건지 미리 예측해놓는 기법을 이용하여 제어 위험 극복
구조적 위험
정의: 명령어 파이프라이닝을 과도하게 수행할 경우, CPU 내에 한드웨어를 효과적으로 사용하기 위한 파이프라이닝이었으나, 같은 타이밍에 한 부품을 여러 명령어가 사용하려고 시도할때 발생
해결기법
- 파이프라인 조정: 단계조정, 사용 시점 조정 하여 동시에 접근하는 것을 막아야만 한다.
슈퍼스칼라
명령어 파이프라인을 인출단계 수행 여러개 해석단계 수행 여러개 등 코어의 각 부품들이 더 쉬지않고 일하게끔 여러 파이프라인을 두고 돌리는 방식을 슈퍼스칼라라고 함.
위험성은 더 증가하지만, 동시수행 능력은 향상.
하드웨어, 소프트웨어 성능을 더 증가시켜야함.
비순차적 명령어 처리
현대 CPU의 새로운 개념인데 더 똑똑해진 처리 방법의 일종이다. 순차적처리에서 나오는 여러 이슈들 중에 특히 데이터 위험이 이에 많이 해당하는데, 스텔링을 해야되는 경우가 발생할때가 있다. 이때 막힘없이 처리하기위한 명령어 수행을 미리 앞당겨 수행하여 전체 흐름을 최적화는 방법이 비순차적 명령어 처리이다.
컴파일러가 소스코드를 빌드하듯이 명령어 처리 순서에 대한 데이터 의존성 분석 처리가 가능한 프로세서여야한다. 즉 고급 CPU여야 한다.
확인문제
- 2번
- 비순차적 명령어 처리, 슈퍼스칼라
05-3 CISC와 RISC
명령어 집합
명령어 집합: instruction set
명령어 집합 구조: ISA, instruction set architecture
CPU가 이해할 수 있는 코드는 기계어이고 바이너리 코드이다.
그런데 CPU제조사는 하나만 있는게 아니다. 따라서 CPU의 언어도 여러개이다. 이런 CPU의 언어인 명령어의 집합 구조인 ISA는 여러 종류가 있다.
대표적인게 CISC, RISC 이다.
CISC
Complex Instruction Set Computer
대표적으로 x86, x86-64 등이 있음.
특징은 명령어의 종류가 상다하며, 이는 가변길이 명령어들이다. 여러 역할을 하는 명령어들을 이용해서 문장을 구성하니 소스코드 자체가 최적화 되어 길이가 짧게 작성가능하다. 이는 소스코드를 올려야하는 메모리 공간을 적게 차지하는 효과.
but 명령어 파이프라이닝을 더 많이 처리할때 CPU입장에서 점점 설계가 어려워지게 된다. 명령어 하나가 복잡한 기능을 담고 있으니, 해석하는데 오래 시간이 걸릴 수도, 메모리 접근을 더 복잡하게 할 수도 있는 형태라 딱딱 정해진 사이클에 맞춰 부품을 점유하게 하면 되는 형태가 아니라 각 명령어가 부품 점유 필요 시간이 제각각이라, 파이프라이닝 위험에 더 많이 노출되는 것.
RISC
Reduced Instruction Set Computer
특징은 명령어의 종류가 매우 적다는 것, 고정길이 명령어라는 점. 단순하고 역할이 구별된 명령어들을 이용해서 프로그램을 구성해야되다보니 명령어를 아주 많이 사용해야되서 메모리에 올라가야되는 용량 자체가 커지게 된다.
하지만, 명령어 파이프라이닝을 수행할때 명령어가 짧게 치고 빠지는 형태로 구성되어 있어 일관된 파이프라이닝을 보장한다.
확인문제
- 4번
- 1번
2주차 (1/13 ~ 1/19) | Chapter 04 ~ 05 | p. 125의 확인 문제 2번, p. 155의 확인 문제 4번 풀고 인증하기 | Ch.05(05-1) 코어와 스레드, 멀티 코어와 멀티 스레드의 개념을 정리하기 |
---|
'Learn > 혼자 공부하는 컴퓨터구조 운영체제' 카테고리의 다른 글
[혼공컴운][3주차] CH06~08 메모리, 캐시메모리, 보조기억장치, 입출력장치 (1) | 2025.02.04 |
---|---|
[혼공컴운] 1주차 Chapter 01 ~ 03 (0) | 2024.12.31 |