computer architecture overview
태그: 운영체제
23.03.06 2주차
컴퓨터구조 overview
Processor Register
- load: cpu가 data를 메모리에서 읽어오는 연산
- store: cpu가 data를 메모리에 저장하는 연산
Register
- ‘data’ I/O를 위한 register
- Control and status registers
- used by processor to control operation of the processor
- Used by privileged operation-system routines to control the execution of programs
- User-visible registers
- MAR(Memory address register): cpu가 메모리에서 데이터를 읽어올때(load) 어느 위치에서 데이터를 읽어올지 주소가 필요한데, 그 주소를 저장하는 레지스터를 의미한다.
- MBR(Memory buffer register): store할 때, 메모리에 저장할 데이터를 저장해놓은 레지스터, load할때는 메모리에서 가져온 데이터를 저장한다.
MAR, MBR은 기본적으로 메인메모리에 대해서 데이터를 읽고 쓸때 사용된다.
폰노이만 머신에서 cpu는 메모리(주기억장치)만 알고, I/O에 대한 존재는 전혀 모른다.
따라서 I/O는 메모리를 통해서 이뤄지는 것이다.
- I/O가 발생하는 과정: 모든 I/O 디바이스는 I/O를 담당하는 기기안에 controller가 다 들어가 있다. 그 컨트롤러는 그 하드웨어 i/o 디바이스를 제어하게된다. controller 안에는 조그만 버퍼 메모리가 들어가 있다. 그 버퍼 메모리 주소를 main memory(주기억장치)의 특정 주소 영역에 mapping 시켜버린다. 그러면 cpu가 그 주소에 뭔가 data를 쓰면, 그것이 I/O가 된다. (ex. i/o 버퍼에서 load하면 i/o기기에서 읽어오는거임.) 즉 cpu는 그냥 메모리 연산을 하는것과 같다.
- User-visible register: 사용자가 직접 건드릴 수 있는 레지스터이다. 예를 들어서 코드에서 자주 실행되는 부분(ex: loop)의 어셈블리 코드를 효율적으로 짜면 프로그램의 성능이 굉장히 향상될 수 있다. 그럴때 쓰라로 있는 부분이라고 함… 나머지 레지스터들은 개발자가 직접 접근할 수가 없다. 반드시 운영체제를 통해서 접근할 수 있다.
Control and Status Register
cpu의 동작을 제어하고, 연산 결과에 대한 상태를 저장
cpu의 동작을 제어한다는 것은 뭘까?
코드를 실행할때, 코드가 메모리에 올라와 있다. cpu가 프로그램을 실행한다는 것은 cpu가 메모리에 올라와 있는 명령어들을 가져와서 실행하는 것이다.
- PC(program counter): contains the address of an instruction to be fetched. 즉 다음에 실행할 명령어의 메모리 주소를 담고 있는 레지스터이다. cpu가 프로그램을 실행하려면 가장 먼저 pc에 있는 주소 값을 읽어와서 그 주소의 메모리에 접근을 한다. 그 메모리에서 명령어를 가져오면 그 명령어를 IR(instruction register)에 저장한다.
- IR(instruction register): 지금 실행해야하는 명령어. 이걸 이제 실행하면 된다.
이제 한 명령어 실행했으면 PC값(주소값)이 1씩..??증가한다. (다음 명령어)
instruction register는 가져온 명령어를 저장..?
program status word
- PSW(program status word): Condition codes라고 한다. 명령의 실행의 결과를 저장하는 레지스터이다. 왜 이걸 가지고 있을까?? → ex: 방금 덧셈을 했다고 치자, 그럼 그 결과가 음수인지, 양수인지, 0인지, 오버플로우인지를 저장해놓는것. → 이유는?: 문제가 생겼는지 빨리 해결하기 위해서이다. cpu 안에서 기본적인 문제를 빠르게 걸러내기 위함임
- Interrupt enable/disable: 얘가 program status word에 해당하는 레지스터..? 현재 인터럽트를 허용하냐 허용하지 않냐를 담고 있음. (나중에 다시 설명해 주신다고 하심
- Supervisor/user mode: 나중에 말해주신다함..ㅋㅋ
문제를 어떻게 찾을것인가.. 컨디션 코드에 들어가 있는 값들을 보고 문제가 있는지 없는 기본적인 검사를함?
Instruction Execution
cpu가 명령어를 실행하는 과정을 간략하게 알아보자
아래 단계가 계속 반복됨
- Instruction Fetch: PC에서 명령어가 있는 주소값을 읽어와서, 그 메모리 주소에 접근해서 Instruction을 읽어와서 IR에 저장하는 단계
- Execute: IR에 담겨진 instruction을 실행하는 단계
fetch, execute가 계속 반복된다.
fetch가 일어난 다음에는 PC의 값이 1 증가한다.
fetch → Pc + 1 → execute
Instruction Register (IR)
IR에 저장되는 명령어들은 크게 4가지이다.
- Processor-memory: load, store 같은 명령이다. 프로세서와 메모리 사이의 data transfer
- Processor-I/O: data transferred to or from a peripheral device
Characteristics of a Hypothetcal Machine
처음 opcode 4bits
address 12bits
Program Counter(PC) = Address of instruction
Instruction Register(IR) = Instruction being executed
Accumulator(AC) = Temporary storage
- 0001 = Load AC from Memory load 명령임. 뒤 메모리 주소로부터 데이터를 가져와서 AC에 넣으라는 말
- 0010 = Store AC to Memory store 명령임. 뒤 메모리 주소에 AC에 있는 데이터를 넣으라는 말
- 0101 = Add to AC from Memory 메모리에 있는 값을 읽어서 AC에 있는 값에 더하라는 말
Example of Program Execution
PC(300): 300번지로 가서 instrution을 가지고 와라
메모리 300에는 1940이 있음. 이걸 IR에 저장
IR(1940): opcode 1 == load. 메모리 주소 940에 가서 로드해오셈
AC에 3이 저장됨.
PC(301): 메모리주소 941에 가서 거깄는 값 AC에 더하셈
AC(3+2) 해서 AC에 저장됨.
PC(302): 941번지에 가서 AC에 있는거 store하셈
Interrupt & Interrupt handler
interrupt the nomal sequencing of the processor
- interrupt: cpu가 진행하고 있는 정상적인 sequencing을 잠시 멈추고, interrupt 된것을 잠깐 처리해줌
- ex. 사용자가 동영상을 플레이 중(현재 하고 있는 instructions), 마우스를 움직임(interrupt) 이럴때, 동영상 플레이 instructions를 잠깐 멈추고, 마우스를 움직이는 코드로 점프해야한다. 그런 코드를 interrupt handler라고 부름. 하던 일을 멈추고 handler 코드로 점프. handler 코드는 운영체제(OS)안에 있는 코드이다. 그 코드를 cpu가 실행함. 다하면 다시 i+1로 돌아옴 즉 정리하면 interrupt가 오면 interrupt handler로 점프하는 것.
Most I/O devices are slower than the processor
대부분의 I/O 디바이스는 프로세서보다 느림. 엄청나게 느림
cpu는 빠른데 I/O가 느려터짐
그럼 i/o가 일을 다 할 때까지 cpu가 기다려야함. → 전체적인 프로그램의 수행이 느려진다.
이럴때 interrupt를 쓰는 거임.
ex)
CPU 입장에서는 interrupt가 왔는지 안왔는지를 알아야한다.
→ 그래서 그걸 체크하는 인터럽트 체크 단계를 추가함
Interrupt Cycle
시작 → fetch → execute → interrupt check
*다만 여기서 interrupt check 단계는 interrupt enable/disable 레지스터의 값에 따라 안할 수도 있음
execute 한 다음에 새로운 인터럽트가 왔는지 체크한다.
인터럽트가 왔다면? → 인터럽트 핸들러 코드로 점프한다.
인터럽트가 안왔다면? → 다시 fetch 단계로
만약 지금 cpu가 하는일이 절대 중단되면 안되는 중요한 일이라면?
→인터럽트가 오더라도 인터럽트를 처리하지 않고 하던 일을 계속함. 즉, 인터럽트 체크를 하지 않고 execute 다음에 바로 fetch로 감
그럼 중요한 일을 하는지, 안하는지를 어떻게 알 수 있을까?
아까 Control & Status register 중에 interrupt enable/disable 레지스터가 있다고 했음. 중요한 일을 시작하기 전에 그 레지스터를 셋해서, 인터럽트가 disable하게 만든다.
Interrupt Processing
인터럽트를 처리하는 과정을 알아보자.
인터럽트는 i/o 디바이스가 발생시킨다.
- 하드웨어
- 디바이스 컨트롤러나 다른 하드웨어가 인터럽트를 발생시킨다.
- 프로세서가 지금 실행하던 명령어를 다 실행함
- 프로세서가 인터럽트를 감지함
- 프로세서가 PSW와 PC 레지스터에 담긴 값(==현재 상태)을 control stack에 저장함
- 프로세서가 인터럽트를 처리하기 위한 새로운 PC 값을 읽어온다. (참고. 인터럽트 핸들러 코드는 OS 안에 들어있는 코드이다. 이때 PC는 인터럽트 핸들러 코드로 넘어가기 위해, OS안에 인터럽트 핸들러가 저장된 위치가 된다.)
- 소프트웨어
- 하드웨어-5번까지 한다음, 일반적인 레지스터의 값을 다 저장한다.
- 이제 인터럽트 핸들러 코드로 넘어가서 해당 코드를 실행한다.
- 실행이 끝나면 원래대로 돌아와야한다. 아까 저장해놨던 레지스터 값들을 다시 복구한다. (Restore)
- PSW, PC도 Restore
Changes in Memory and Registers for an Interrupt
인터럽트를 처리하기 위해 메모리와 레지스터에서 일어나는 일들을 알아보자.
stack pointer → 스택의 top을 가리키고 있는 포인터
sp로 가서 general register 값들을 다 저장을 하고, PC 값도 저장을 하고, 바뀐 stack top pointer를 sp에 다시 저장한다. (T-M)
이제 PC에 새로운 PC값(인터럽트 핸들러 주소)를 저장한다.
Program Flow of Control Without Interrupts
인터럽트가 없다면 어떻게 될까??
*시스템콜: I/O를 수행하는 운영체제 코드? fprintf 같은 함수를 뜯어보면 안에 시스템콜이 있다.
인터럽트가 있다면 I/O를 하게 됨. 4번 밑에 I/O Command는 cpu는 아무것도 안하고 하드웨어가 바쁜시간이다. cpu가 아무일도 하지 않기 때문에 idle 타임이라고 한다.
우리가 원하는건 cpu의 idle 타임이 없는 것이다..!!
Program Flow of Control with Interrups: Short I/O wait
인터럽트를 이용해서 CPU를 놀리지 않는 방법(?)
CPU는 인터럽트 또는, IO가 발생하면 그냥 하드웨어한테 일 시키고 다시 돌아와서 계속 명령어 fetch, execute함
하지만 지금 이 케이스는 short IO case이다.
이게 가능한 이유는 short IO case이기 때문이다. IO가 빨리 다 끝나고 2a를 하고 인터럽트를 issue한것임. (즉 2를 진행하는 중간에 인터럽트를 받은것)
만약 IO하는 시간이 길어져서 2번을 하고도 IO가 끝나지 않은 상황이면 어떡할까?
그렇다면 2가 끝나도고 인터럽트를 받을 수 없는데 어떻게 될까.
Long I/O wait
최적화 중에 I/O 순서 바꾸는 최적화도 있음
어쩔 수없이 4번 I/O가 끝날때까지 cpu가 기다려야한다ㅠ
I/O가 끝나서 인터럽트가 오면 인터럽트를 처리한다.
3번을 실행하고, 아직 인터럽트 처리가 끝나지 않았기 때문에 또 기다린다.
마지막 Write 처리
인터럽트는 만병 통치약이 아니다..
그래서 또 cpu를 일키실 방법이 있음
Multiprogramming
여러개의 프로그램을 동시에 실행하자!
여러개의 프로그램이 메모리에 탑재돼서 실행가능한 상태가 되면 멀티프로그래밍이라고 한다.
data 간에 dependency가 없는 다른 프로그램의 i/o를 실행. (cpu가 할일이 있을 때 계속 일할 수 있다.)
현재 수행되는 아무 프로그램으로만 돌아가면 된다.
즉 어느 프로그램으로 돌아가든, cpu가 일만 하면 됨
단점: 관리가 복잡해짐
장점: 효율성
- 멀티 프로그래밍에서는 cpu를 나눠쓴다는 개념이 없음. 근데 그냥 구현한 김에 cpu 스케줄링(멀티 태스킹)까지 구현. 여러 프로그램이 동시에 실행되는 것처럼 느끼게 함. (시분할, 멀티 태스킹)
- 멀티 태스킹은 멀티 프로그래밍이 구현돼있는 환경에서만 가능하다.(일단 메모리에 프로그램이 올라와 있어야하니까. 멀티프로그래밍은 멀티태스킹의 기반 기술이다.)
참고(질문)
- 인터럽트 체크를 fetch 다음단계에 하면 안됨?
- 안될건없는데, 장점이 없고 단점만 있음. execute 단계 다음에 하면 IR를 저장할 필요가 없는데, fetch 다음에 인터럽트 체크하면 IR도 저장해야함(오버헤드가 늘어남)
- 만약 long i/o때문에 다른 프로그램으로 넘어갔는데, 우연히 같은 데이터에 접근하면 어떡함?
- 한 프로그램이 데이터에 접근하는 동안 다른건 접근하면 안됨(공유 자원에 lock을 걸어놓음)
- 만약 저장장치가 HD가 아니고 SSD여도 똑같은 로직으로 구현?
- ㅇㅇ. 그래도 되는 속도임. SSD가 HD보단 빠르지만(물리적인 움직임이 없기 때문에) 그래도 cpu보단 느림
- 플래시 메모리는 데이터 덮어쓰기가 안됨. 그래서 update가 일어나면 새로운 데이터를 다른 곳에 쓰고 원래 데이터를 무효화 시킴. 그리고 나중에 지움..? → 이게 맞나..?
- 컴퓨터를 켜면 ROM이 실행되고, 걔가 하드디스크에 있는(맞나..?) 부트스트랩코드를 메모리에 올려줌(진짜 부팅하는 코드)