본문 바로가기

IT개발/컴퓨터구조

컴퓨터 구조관련 정리(1)

목표> 프로그래머 관점에서 머리속에 컴퓨터의 전체적인 그림을 그리자.

 

시스템 프로그래밍에 대한 (폭넓은) 정의 :

 

시스템 프로그램 - 컴퓨터 시스템을 동작시키는 프로그램

                         (동작 - 파일복사나 파일이동 등과 같이 우리가 상식적으로 생각할때 기본적인 동작이라 간주하는 것들)

 

그럼 대표적인 시스템 프로그램은?

 - Windows, Unix 와 같은 운영체제 = 하드웨어를 모르는 사용자들이 컴퓨터 쉽게 사용할 수 있도록 도와줌

 

 

컴퓨터 시스템 - 보통 하드웨어 뿐만 아니라 + 하드웨어가 실제 일을 하게끔 도와주는 운영체제를 포함

 

시스템 프로그래머 ?

1) 어셈블리. c언어 이용하여 하드웨어 직접컨트롤 하는 개발자

2) 운영체제 개발자

3) Windows 나 Unix 같은 운영체제에서 제공하는 라이브러리(운영체제의 기능을 활용할 수 있는 시스템 함수의 집합)를 사용하여

    프로그램 개발하는 개발자

 

둘다 모두 시스템 프로그래머라 부를 수 있다.

 

즉, WIndows에서 제공하는 라이브러리를 활용하여 프로그램 개발하면 Windows 시스템 프로그래머가 되는거고,

     Unix에서 제공하는 라이브러리를 활용하여 프로그램을 개발하면 Unix 시스템 프로그래머가 되는 것이다.

 

 

휼륭한 시스템 프로그래머가 되기위한 결론?

   - > 운영체제와 (운영체제를 이해하기 위한)컴퓨터구조에 대해 잘 알자.

 

 

 

※ 컴퓨터 시스템의 주요 구성요소 (Main Components)

 

CPU <-> 캐쉬(Cache) <-> 메인메모리(Main Memory) <-> 하드디스크 (Hard Disk)

------ 컴퓨터 구조 -----     ------------------- 운영체제 ----------------------

 

보통 대학에서는

 

1) CPU와 캐쉬의 내용은 컴퓨터 구조(Computer Architecture)에서

2) 메인메모리(Main Memory)와 하드디스크(Hard Disk)에 대한 내용은 운영체제(Operating System)이라는 과목에서 다룬다.

 

이 둘을 잘 알아야 전체 시스템을 이해할 수 있다.

 

                      

 

 

※ 컴퓨터 하드웨어의 구성

 

 

                   CPU(Central Processing Unit)

------------------------------------------------------------

ALU(Arithmetic Logic Unit) <--->  레지스터 (Register Set)

                                                      ↑  

                                                      ↓                                                -----------------------------

컨트롤 유닛(Control Unit)            버스 인터페이스(Bus Interface)               메인 메모리(Main Memory)          

------------------------------------------------------------              -----------------------------

                      ↑                                                                                                    ↑

                      ↓                                                                                                    ↓

 =======   입출력 버스 (I/O BUS) ==================================================================

       ↑                 ↑                      ↑                         ↑

       ↓                 ↓                      ↓                         ↓

    키보드          모니터           네트워크카드           하드디스크

 

 

 

 

1) CPU(Central Processing Unit) : 컴퓨터의 머리 -> 바로 뒤에서 자세히 알아보자

 

 

2) 메인메모리(Main Meomory) : 컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역 (프로그램 실행을 위해 존재하는 메모리)

                                             예) 하드에 저장되있는 게임실행시 -> 더블클릭. 해당프로그램은 메인메모리로 올라가서 실행된다.  

 

 

3) 입출력 버스(Input/Output Bus) :  컴퓨터 구성하는 요소 사이에서 데이터를 주고 받기 위해 사용되는 경로

                                                  어드레스 버스(Address Bus), 데이터 버스(Data Bus), 컨트롤 버스(Contro Bud) 세가지로 구분

 

 

버스의 역할 :  버스 시스템을 기반으로 하드디스크 <---> 메인 메모리 사이 데이터 전송가능

                      메인 메모리와 CPU 사이에서의 데이터 입.출력도 가능

 

 

 

 

※ CPU에 대한 이해

 

CPU(Central Processing Unit)

------------------------------------------------------------

ALU(Arithmetic Logic Unit) <--->  레지스터 (Register Set)

                                                      ↑  

                                                      ↓                                               

컨트롤 유닛(Control Unit)            버스 인터페이스(Bus Interface)              

 ------------------------------------------------------------ 

 

1) ALU:

 

 연산을 담당 / 그외의 블록은 연산을 하는데 도움을 주는 블록들이다.

- 산술연산(덧셈, 뺄셈)과 논리연산(AND, OR)가 이루어진다.

 

 

2) 컨트롤 유닛:  CPU가 처리해야 할 명령어들을 해석한다. (CPU의 총사령관)

 

CPU 내부로 다음과 같은 32bit 명령어가 전송되었다고 가정해보자.

"10011010 00011010 10011110 10010011"  

ALU 가 이 명령을 이해할 수 있겠는가? ALU는 산술.논리연산만 할 줄아는 단순한 놈이다. 따라서

누군가 이 명령어를 해석해 줘야 한다. 이러한 도움을 주는 구성요소가 컨트롤 유닛이다.

 

예를 들어 컨트롤 유닛은 CPU 내부로 흘러들어오는 명령어를 보고 다음과 같은 결정을 내린다.

"아하 이 명령어는 덧셈을 하라는 뜻이군!. 그렇다면 ALU에게 뎃셈을 하도록 신호보내야지~"

 

이처럼 컨트롤 유닛은 명령어를 해석하고, 그 해석된 결과에 따라 적절한 신호를 CPU의 다른 블록에

보내는 일을 한다. 훔.. CPU의 총사령관정도로 생각하자.

 

 

3) CPU 내부에 존재하는 레지스터들(Register Set) : CPU내부에 존재하는 2진데이터(Binary Data) 저장을 위한 저장장치

 

덧셈을 위해서 덧셈 명령어만 흘러 들어가면 되는가? 뎃셈의 대상, 즉 피연산자도 함께 들어와야 한다.

그렇다면 이들 명령어와 피연산자를 cpu의 어느 요소로 보냐면 좋겠는가?

 

명령어         -> 컨트롤 유닛

피연산자 5,9 -> ALU

 

로 보내면 된다. 그러나 현재 ALU가 연산중이고 컨트롤 유닛은 앞서 들어온 명령어를 해석하는 상황이라면?

불가능할수 있다. 때문에 컨트롤 유닛이나 ALU가 필요로 하는 명령어와 데이터들을 어디엔가 저장해 두고

상황이 허락될 때 직접가져가게 만들면 좋을것이다.

 

다시 말해, CPU 내부에도 임시적으로 데이터를 저장하기 위한 조그마한 메모리 공간이 필요하다.

다행히 레지스터(Register)라는 아주 작은 메모리가 CPU내에 존재한다.

 

이런 레지스터들은 cpu내부에 여러개가 존재하며, cpu의 종류에 따라서 그 개수와 형태가 다양하다.

레지스터들은 용도가 정해져 있는 것이 일반적이며, 이들은 cpu가 연산을 하기 위해 반드시 필요하다.

아주 기본적인 레지스터만 8개가 넘는다.

 

 

 

 

※ 버스 인터페이스 (Bus Interface)

 

 

                   CPU(Central Processing Unit)

----------------------------------------------------------------

ALU(Arithmetic Logic Unit) <--->  레지스터 (Register Set)

                                                      ↑  

                                                      ↓                                               

컨트롤 유닛(Control Unit)            버스 인터페이스(Bus Interface)                         

-----------------------------------------------------------------             

                      ↑                                                                                                   

                      ↓                                                                                                   

 =======   입출력 버스 (I/O BUS) ==================================================================

 

 

 

컴퓨터 뚜껑을 열면, CPU, 하드디스크, RAM, 사운드 카드, 그래픽 카드등을 어렵지 않게 찾을수 있다.

이들은 서로 독립적으로 존재하는 것이 아니라 서로 데이터를 주고받으면서 동작한다.

 

그럼. 서로 데이터를 주고 받기 위해서는 어떠한 매개체가 있어야 할까? 바로 I/O BUS 다

 

 

그림을 보면 CPU는 I/O 버스에 접근이 가능한 것으로 보인다. 이 버스에 접근해서 데이터를 전송하고 입력받기도 한다.

하지만 그렇게 쉬울까? 지하철이나 비행기도 이용방법을 알아야 탑승하는 것처럼, I/O버스의 통신방신을 이해하지 못하면

데이터를 보낼수도 받을수도 없다.

 

즉, CPU 내에는 I/O 버스의 통신방식을 이해하고 있는 그 무엇인가가 있어야만 한다.

 

이게 바로 버스 인터페이스(Bus Interface)다.

이 버스 인테페이스 장치는 버스가 어떻게 데이터를 전송하는지,그에 대한 프로토콜 혹은 통신방식을 알고 있는 녀석이다.

 

 

 

 

※ 클럭 신호(Clock Pulse)

 

클럭신호는 cpu를 구성하는 요소는 아니다. 하지만 cpu를 구성하는 요소에 제공되어야 하는 신호로써,

아주 중요한 의미를 지닌다. 클럭신호는 타이밍(Timing)을 제공하기 위해서 필요하다.

 

예) 당신의 cpu사양은 어떠한가?

     예를 들어 cpu 클럭속도가 1.6Mhz라면, 클럭발생기(오실레이터)는 1초당 1,600,000 번의 클럭을 발생시키게 설정된다.

     참고) 요즘 클럭발생기(오실레이터)는 메인보드(Main Board)에 포함되어 있다.

 

     cpu는 매 클럭이 발생할때 마다 그 클럭에 맞춰서 일을 한다. 즉 클럭속도가  1.6Mhz인 CPU는 1초에 1백6십 만번 일(연산)을

     하는것이다. 

   

     -> 따라서 CPU클럭속도가 높으면 초당 처리하는 명령어의 개수가 많아지므로, 컴퓨터의 전체적 성능은 좋아지기 마련이다.

  

 

그럼 질문을 하나 해보자.

 

" CPU는 왜? 클럭신호에 맞추어 일을 해야만 하는가? " 클럭신호가 발생할때마다 일하면 CPU가 많이 노는거 아닌가?

 

-> 그러나 컴퓨터 시스템은 동기화를 필요로 한다.

 

무슨말이냐고? 간단히 설명을 해보겠다.

 

 

 

< 1번 그림 >

 

input1      input2

  ↓             ↓

    + 연산장치     

          ↓                    

     BUFFER      

          ↓                   

      출력장치     

 

 

 

< 2번 그림 >

 

input1      input2

  ↓             ↓

    + 연산장치     <-----

          ↓                    |

     BUFFER       <-----

          ↓                    |

      출력장치      <------------------- 클럭신호(Clock PULSE)

 

 

 

두 그림이 무슨차이가 있을까?

 

1번그림은 별문제 없어 보일수 있다. 하지만 문제상황 예를 들어보자.

 

만일 input1, 2를 통해 데이터가 계속 들어오고 있다. 따라서 + 연산장치는 계속해서 '+' 연산처리를 하며

출력장치는 BUFFER에 존재하는 데이터를 계속 가져다가 출력해야 한다.

 

근데 만일에 +연산장치와 출력장치의 속도가 다르다면??

 

만약 출력장치의 속도가 더 빠르면, 출력장치는 이미 한번 가져간 데이터를 다시 가져가 출력하는 문제점이 드러날수 있고,

+연산장치가 더 빠르다면 , 버퍼를 덮어쓰여 연산결과 일부가 출력되지 않을수도 있다.

 

그럼 어떻게 해결하면 될까?

 

당연히 속도가 느린장치에 장단을 맞추면 된다.

예를 들어, + 연산장치 속도가 더 느리면 클럭신호 발생속도를 +연산장치에 맞춰놓고, 데이터를 이동시키면 되는 것이다.

 

 

 

Note) 요즘 임베디드 시스템이 하나의 이슈가 되면서 ARM이나 MIPS와 같은 코어들을 직접 다루는 개발자들이 늘고 있다.

         이런 작업을 하면 코어들의 클럭을 프로그램상에서 직접조절하는 경험을 해볼수 있다.

         이때 클럭을 높이되 어디까지 높이느냐가 종종 관건이 되기도 한다. 최대한 클럭을 높이는 거는 좋지만, 특정 범위이상

         으로 높이면 시스템이 불안정하게 동작하기 시작할수 있다. 시스템을 오버 클러킹해서 사용하다가 CPU 고장난적 없는가?

 

 

 

 

※ 프로그램의 실행과정

 

프로그램의 실행과정은 어떻게 될까?

 

* 폰 노이만의 컴퓨터 구조

 

초창기 컴퓨터

- 임의의 연산하고자 할때마다 여러명의 엔지니어가 달라붙어 진공관 회로의 스위치를 변경해준다. (그냥 상상해 봐라)

 

폰노이만 컴퓨터 구조

 

 

CPU  <---->   메모리 <------ 프로그램 Load한다.

 

 

위 그림에서 중요한 부분은 메모리와 프로그램이다.

 

이전까지는 프로그램이란 단순히 진공관 회로의 스위치 구성을 의미했지만,

폰 노이만은 프로그램이 컴퓨터의 내부에 저장되는 구조 생각해 낸 것이다.

 

= "Stored Program Concept"

 

 

 

 

[ 프로그램의 실행과정  ]

 

전처리기 -> 컴파일러 -> 어셈블리 -> 링커

 

 

1) 전처리기에 의한 치환작업

 

2) 컴파일러에 의한 번역

    ->만약 이게 없었으면 어셈블리언어를 익혀서 프로그램 작성했어야겠지.

 

3) 어셈블러에 의한 바이너리 코드 생성

   -> 바이너리 코드는 그냥 텍스트 코드의 상대 개념으로 생각해라. 0과 1로 구성되는 코드

        컴파일러에 의해 번역된 어셈블리 코드는 컴퓨터에 의해 실행되야 하므로 바이너리 코드로 변역되어야 한다.

 

예) add 0011

      min 0010

      mul 0100

      div  0101 로 정한다고 하자.  이걸 테이블로 만들어보자

 

어셈블러 : 어셈블리 코드 -> 위와같은 테이블을 참조해서 cpu가 이해하는 바이너리 코드로 변경해주는 프로그램

 

 

4) 링커에 의한 연결과 결합

프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶는(혹은 연결시켜주는) 작업

 

이 과정이 끝나면 실제로 실행 가능한 실행파일이 생성된다. (물론 컴퓨터가 실행해야 하는 바이너리 코드다)

 

자, 이제 이 실행파일과 폰노이만의 "Stored Program Concept"을 하나로 묶어 프로그램 실행을 생각해보자

 

 

 

 

CPU     ---------------------  메모리   <------------------------ 실행파일 Load

 

 

실행파일들은 메모리에 올라가고 나면, CPU에 의해 실행된다.

메모리 공간에 올라간 명령어들은 CPU에 의해 순차적으로 실행된다.

 

Fetch     : 메모리상에 존재하는 명령어를 cpu로 가져온다.

Decode  : 가져다 놓은 명령어를 cpu가 해석하는 단계 

               예) 명령어 A -> 덧셈이라는 의미로 해석된다.

 

Execution : 해석된 명령어의 명령대로 cpu가 실행하는 단계 (덧셈실행)

 

 

 

 

 ※ 배운거 최종 마무리 정리

 

- 우선 아래 질문 4가지에 답해봐라

 

1) 명령어 실행을 위해 제일먼저 하는 일이 Fetch인데 어떠한 이동경로 통해서 명령어의 Fetch가 진행되는가?

2) 명령어를 cpu안에 가져다 놓을깨 어디에 저장하는가?

3) cpu 안에 가져 다 놓은 명령어는 Decode 단계에서 해석되는데 이는 cpu안에 존재하는 누가 진행하는가?

4) 마지막 단계인 Execution은 누구에 의해 실행되는가?

 

 

당연히 대답을 할 수 있어야 한다. ^^ 모르겠다면 밑의 내용을 보자

 

 

                   CPU(Central Processing Unit)

------------------------------------------------------------

 

ALU(Arithmetic Logic Unit)      ----  레지스터 (Register Set)

                                        |               

                (Execution)     |                                                             -----------------------------

컨트롤 유닛(Control Unit)    <-|       버스 인터페이스(Bus Interface)               메인 메모리(Main Memory)

                   (Decode)                                                                                       명령어 A          

------------------------------------------------------------              -----------------------------

                      ↑                                                                                                    

                      ↓                              ↑                                                                     ↓   (Fetch)

 =======   입출력 버스 (I/O BUS) ==================================================================

       ↑                 ↑                      ↑                         ↑

       ↓                 ↓                      ↓                         ↓

    키보드          모니터           네트워크카드           하드디스크

 

 

 

이제 머리속에 잘 정리가 되는가?

 

그럼 1장은 이 정도에서 정리하기로 하자.