안녕하세요~


이번시간에는 CPU의 스펙중 가장 큰 부분을 차지하는 코어와 스레드라는 개념에 대해서 알아보도록 할게요!


이번 시간은 다른 시간과는 다르게 C언어의 지식이 어느정도 있어야 이해가 가능해요ㅜㅜ

(그런데 조금 읽어보니 필요없을수도 있는것 같아요 ㅎㅎ)




<1.Program>


컴퓨터의 CPU는 메모리에서 명령어를 읽어드린다는 사실 기억하시죠? 또한 내가 어떤 프로그램을 수행시키려면 해당 프로그램이 Disk(SSD,HDD)에서 메모리에 업로드가 돼야한다는 사실도 기억하실거에요!


(기억이 안나시면 이 챕터를 참고해주세요! --> 링크)



그렇다면 프로그램이라는건 어떻게 구성되서 CPU에서 차례대로 진행되는 걸까요?


프로그램은 프로그래밍 언어로 구성되어 있어요. 아래 사진에서 C언어로 구성된 프로그램이 만들어 졌다고 가정해볼게요. C언어로 만들어진 프로그밍 언어들은 각각 역할에 따라 고유의 영역으로 나뉠 수 있어요. 


<사진1>


Code영역: for, while, if 와 같은 조건문이나 상수값 같은 경우는 코드가 실행되는 중간에 변경이 불가능해요. 그래서 컴파일(Compile) 과정에서 아예 기계어로 변경시켜 읽기전용(Read-Only)으로 만들어 놓은 곳이라고 보시면 될거에요. 예를들어, hex, bin 파일이 code영역에 해당되는 곳이라고 보면 되겠네요!


Data영역: 데이터 영역은 전역(global), 정적(static) 변수, array, 구조체(structure)가 저장되는 곳이에요. 지금 나열한 요소들의 특징은 프로그램이 종료되기 전까지 없어지지 않고 메모리 영역을 차지하고 있는다는 점이에요. 하지만 해당 값들은 변경이 될 수 있기 때문에 컴파일(Compile)과정에서 기계어로 번역되지는 못하고, 메모리에 크기만 결정되게 됩니다.


BSS영역: Data영역과 대부분 유사하나 BSS영역은 초기화되지 않은 전역, 정적 변수, array, 구조체가 저장되는 곳이라고 해요. 



<사진2>



Heap영역: 프로그램을 구성하다보면 의도적으로 프로그램이 동적으로 메모리를 할당받아야 하는 경우가 있어요. 그렇기 때문에 프로그램이 실행하는 중간에 크기가 결정이 됩니다. C언어에서는 malloc(), calloc() 과 같은 함수가 이러한 역할을 하게되는데, 이때 이러한 역할을 하는 요소들을 모아놓은 곳이 heap이에요.


Stack영역: C언어에서 흔히 사용되는 지역변수, 매개변수, 리턴 값 등이 이곳에 해당됩니다. 이곳은 해당 코드가 실행되고 종료되면 바로 사용했던 메모리를 반납합니다. 그래서 이 역시 또한 프로그램이 실행하는 중간에 크기가 계속해서 바뀌게 되는거죠. 


Heap과 Stack 영역은 실행 중간에 크기가 바뀌기 때문에 중간에 해당하는 영역을 일정공간 비워두게 됩니다. 그런데 프로그램 코드를 잘 못 작성하게 되면 서로의 영역을 침범하는 경우가 발생하는데요. Heap 영역이 너무 많이 생겨 Stack 영역을 침범하는 경우는 heap overflow라고 하고, 그 반대는 stack overflow라고 합니다.


<사진3>



이렇게 하나의 프로그램이 완성이되면 하나의 단위로써 Disk에 저장되게 됩니다.






<2.Process>


프로그램을 만들어 Disk(SSD, HDD)에 저장시켰으면 실행시켜봐야겠죠?

우리가 프로그램을 실행시키면 운영체제가 Disk에서 해당 프로그램을 메인메모리에 올려주게 됩니다.


그럼 프로그램이 (CPU가) 실행 가능한 형태로 변경이되는데요. 이때 메모리에 올라가 실행준비가된 프로그램을 process라고 부릅니다. 실제로 process의 정의는 "process is program in execution"이라고 합니다. 



<사진4>



Disk에 있던 program이 메모리에 올라와 process가 되었다는건, 다시말해 program이 CPU가 이해할 수 있는 구조인 process로 변경되었다는것을 의미하겠죠? 그렇다면 CPU가 이해할 수 있는 process의 구조란 무엇을 의미하는걸까요? 답부터 말씀드리면 PCB가 CPU가 이해할 수 있는 process의 (자료)구조라고 할 수 있어요!




<3.PCB(Process Control Block)>


좀 더 구체적으로 CPU가 이해하기 위해서 process는 어떤 구성요소를 갖고 있어야 할까요? 즉, PCB는 어떻게 구성되어야 하는걸까요?


1)PID (Process ID)

- 프로세스의 고유한 번호에요. 당연히 각각의 프로그램의 고유ID가 있어야 서로 고유의 (메모리)영역을 침범하지 않겠죠? 그리고 프로그램간의 통신을 하는 경우도 발생할 수 있으니 서로 누구인지 인식할 수 있는 ID가 있어야 하기 때문에 PID라는 개념이 생겨났어요.


2)State

- Process의 현재상태를 의미해요. 이 부분은 바로 뒤에 CPU Scheduling 부분에서 설명하도록 할게요.



<사진5>


3)Pointer

- process가 위치하고 있는 메모리 주소 정보에요. 각각의 프로세스는 고유의 영역을 갖고 있다고 말씀드렸는데 해당 영역의 위치정보를 갖고 있어야 하기 때문에 Pointer라는 것이 존재해요.


<사진6>



4)Priority

- 이 부분도 CPU scheduling에서 자세히 설명하도록 할게요.


5) Program counter

- 하나의 process 내에서 다음에 실행될 명령어 주소 값을 가지고 있어요


6)I/O information

- Process가 할당 받은 I/O 자원들에 대한 정보에요. 이 부분도 아마 CPU scheduling을 보시면 더 명확히 이해하실 수 있으실 거에요.


7) Accounting information

- CPU를 사용한 시간 정보입니다.



앞서 '2)State, 4)Priority, 6)I/O information 에서 CPU scheduling에 대해서 언급한 바 있었는데요. 간단하게 CPU scheduling이 무엇인지 알아보도록 할게요!






<4.CPU Scheduling>


우리가 컴퓨터에서 작업을 할 때, 대부분 하나 이상의 프로그램들을 실행시키게됩니다. 이때 프로그램들이 메모리에 업로드되어 각각 고유의 process들이 되는데요. 그렇다면 CPU는 아래 그림처럼 process1 작업이 다 끝날때까지 다른 process에는 접근을 안할까요??  만약 Process1을 실행시키다가 굳이 CPU가 하지 않아도 될 작업들이 진행될 때, cpu가 다른 process의 일을 처리하고 다시 process1으로 접근하면 더 효율적이지 않을까요?


<사진7>


위와 같은 질문을 통해 나온 개념이 CPU scheduling이라는 개념이에요. 우리는 운영체제라는 시스템이 CPU가 놀지 않도록 process의 상태에 따라 cpu를 scheduling하도록 설계했답니다. 즉, 수 많은 process가 하나의 CPU를 점유하려고 달려들때 운영체제가 CPU를 문제 없이 점유 하도록 process들을 scheduling(관리) 해준다는 개념인거죠!



<사진8. CPU scheduling>



하나의 예를들어볼까요?


특정 process는 CPU에 의해 실행이 되다가 프린트 또는 다른 입출력 장치를 이용할 경우 다른 process에게 CPU를 양보하게 됩니다. 생각해보면 '워드 2장을 프린트로 출력'하는 행위는 CPU가 하는게 아니라 프린터가 하는거에요. 그래서 CPU가 워드 2장에 대한 내용만 프린터에 전달해주면 CPU의 역할을 끝나게 됩니다. 그런데 CPU가 프린터가 끝날때 까지 기다려야 하나요? 아니죠! 그래서 프린터와 같이 CPU와는 별개의 작업이 진행될 때는 해당 process가 잠시 대기 상태('2)State')가 됩니다.

그런데 만약 프린터작업이 끝났을 경우에는 어떻게 할까요? 만약 워드 프로그램에서 프린터 작업이 마무리 되면 알아서 프로그램이 종료가 되나요? 아니죠! 프린트 작업이 마무리 되려면 CPU가 해당 '워드 프로그램에게 프린터 작업 종료해!'라고 말해야해요. 안그러면 다른 문서를 프린트하려고 하면 '현재 계속 프린트가 작동되고 있습니다'라는 메시지를 전달할거에요...


그래서 프린트 작업이 끝나면 대기가 되었던 process를 다시 CPU가 점유해야해요. 그런데 다른 process들도 있는데 어떻게 CPU를 다시 점유할 수 있을까요? 이러한 문제 때문에 I/O 같은 작업으로 인해 CPU를 양보해주는 process들은 이 작업이 끝나면 가장 먼저 CPU를 점유할 수 있도록 해줍니다. 즉, CPU를 선점할 수 있는 우선권('4)priority')를 제일 높게 설정해주는거죠!




그렇다면 실제로 우리 컴퓨터에서는 얼마나 많은 process가 동작하는지 볼까요?


"윈도우키 -> 작업 관리자 -> 성능 탭" 순서로 보시면 CPU의 process가 얼마나 많이 실행되는지 볼 수 있을거에요.  



이번 시간에는 Process와 CPU scheduling에 대해서 알아봤어요.

Process의 개념과 PCB라는 개념을 이해하고 있어야 core와 thread에 대한 개념을 좀 더 명확히 이해할 수 있기 때문에 다뤄봤습니다.

다음 시간에는 CPU, Memory, 운영체제간의 관계를 좀 더 디테일하게 알아보고 32bit, 64bit가 뭘 의미하는 것이고 CPU에서 x86이라는건 뭘 나타내는것인지 알아보도록 할게요!





[글 래퍼런스]

https://jungwoon.github.io/android/2019/07/16/Process-Thread/



[사진 래퍼런스]

사진1

https://sfixer.tistory.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%ADcode-data-stack-heap

사진2,3

https://aerocode.net/199

사진4

https://copycode.tistory.com/39

사진5

https://jungwoon.github.io/android/2019/07/16/Process-Thread/

사진6

https://docsplayer.org/117139474-Microsoft-powerpoint-o8-pptx.html

사진7

https://slidesplayer.org/slide/14685169/

사진8

https://itdexter.tistory.com/390


+ Recent posts