1. 컴퓨터 동작의 기본 개념

컴퓨터가 하는 일을 간단하게 표현하여 컴퓨터 구성과 동작의 기본 개념을 쉽게 이해할 수 있다.


컴퓨터 모델

계산기 모델

  • 컴퓨터가 하는 일을 가장 간략하게 단순화 시킨 모델.
  • 계산기는 명령어(코드) 스트림과 데이터 스트림을 받아 일련의 결과 스트림을 내보낸다.
    • 코드 스트림(code stream) : 여러 연산(명령어)을 순차적으로 나열한 것.
    • 데이터 스트림(data stream) : 코드 스트림의 연산을 적용할 데이터(피연산자)를 순차적으로 나열한 것.
    • 결과 스트림(result stream) : 코드 스트림을 데이터 스트림에 적용한 연산 결과를 순차적으로 나열한 것.

calculator-model 계산기 모델


  • 수식으로 예를들면 아래와 같다.
    • 데이터 스트림 : 1, 2
    • 코드 스트림 : +
    • 결과 스트림 : 3

calculate 데이터 스트림과 코드스트림 그리고 결과 스트림 예시


  • 계산기 모델은 다음과 같은 작업을 하는 기기로 표현 가능하다.
    • 데이터를 입력받는다
    • 명령어(코드)를 입력받는다
    • 데이터와 명령어를 이용해 연산 후 표기한다.


문서 관리원 모델

  • 컴퓨터를 단순 연산만 하는 계산기가 아닌 일련의 데이터를 읽고(read) 수정/계산 한 후 (modify),
    수정한 데이터를 쓰는(write) 기기로 표현한 모델
  • 컴퓨터가 읽기-수정-쓰기를 수행하기 위해서는 다음 3가지 기본 요소가 필요하다.
    • Storage
      • 저장소
      • 컴퓨터가 데이터를 Read, Write 할때 이 데이터를 저장 또는 불러올 장소.
    • ALU (Artimetic Logic Unit)
      • 산술 연산 장치
      • 저장소에서 읽어온 데이터와 코드의 명령어를 가지고 산술 연산을 수행하는 장치.
    • Bus
      • ALU 와 저장소 사이에서 데이터를 전송하는 통로.

calculator-model 문서 관리원 모델 - 코드와 데이터는 논리적으로 다른 공간에 저장된다.


  • 문서 관리원 모델은 아래와 같은 작업을 반복하는 기기로 표현 가능하다.
    • 저장소에서 필요한 데이터를 가져온다.
    • 저장소에서 필요한 명령어 (코드)를 가져온다.
    • 데이터와 명령어로 연산을 수행 후 데이터를 저장한다.


성능 향상을 위한 추가 구성요소

  • 문서 관리원은 일련의 데이터를 처리하고 반복하는 작업을 한다.
    이 반복된 작업을 어떻게 빠르게 처리할 수 있을까? 의 고민에 해답은 아래와 같다.

레지스터 파일 ( Register File )

  • 실제 연산은 ALU 에서 일어나기 때문에 저장소의 위치는 ALU 에서 가까운게 좋다.
    • 연산을 빠르게 수행하기 위해 빠르게 접근할 수 있는 데이터 저장소를 만든다.
      • 이를 레지스터 라고 한다.
    • 여러 레지스터가 모인것을 레지스터 파일이라 한다.
  • 마이크로프로세서 면적과 같은 현실적 제약 사항을 고려할 때 ALU 근처의 저장소 공간은 그리 커질 수 없다.
    • 저장소 공간의 크기가 매우 적어 실제 코드/데이터 스트림의 일부밖에 저장할 수 없다.
  • 즉 ALU 가 연산을 빠르게 하기 위하여
    ALU 주변에 코드/데이터 일부를 저장할 작은 저장소를 만들어 연산 속도를 향상시킨다.

alu-storage-register 레지스터가 결합된 문서 관리원 모델


  • 레지스터가 포함된 ALU 3 단계 작업
    • 덧셈을 할 2 개의 데이터를 지정된 2개의 소스 레지스터로 읽어온다.
    • ALU 를 이용해 두 수를 더한다.
    • 연산 결과를 목적 레지스터에 넣는다.

RAM

  • 레지스터 만으로는 매우 많은 양의 데이터를 보관할 수 없기 때문에,
    이를 저장할 저장소로 메인메모리 (RAM : Random Access Memory) 가 그 역할을 한다.
    • 위 그림들에서 Storage 는 사실 RAM 이다.
    • 실제 하드디스크는 저렇게 코드와 데이터를 나눠 저장하지 않는다.
  • ALU 연산을 위해서는 메인 메모리의 데이터 중 일부가 레지스터로 옮겨져 사용된다.
  • ALU 와 레지스터는 같은 마이크로프로세서 내부에 있지만
    메인 메모리와는 실제로 별개로 존재하여 메모리 버스를 통해 마이크로프로세서와 연결된다.
  • 거리가 먼 만큼 메인 메모리의 데이터를 버스를 통해 프로세서로 전송하려면 상당한 시간이 필요하다.
    • 레지스터를 통해 메인 메모리의 데이터를 ALU 근처에 저장할 수 있으므로,
      ALU 는 느린 메인메모리를 기다리지 않아도 된다.
      컴퓨터 연산 속도는 메인 메모리의 속도에 의해 제한 되지 않는다.


  • RAM(메인 메모리)이 포함된 ALU 4 단계 작업
    • 메인 메모리에서 2 개의 데이터를 읽어서 소스 레지스터에 넣는다.
    • ALU 를 이용해 두 레지스터의 값을 더한다.
    • 연산 결과를 목적 레지스터에 넣는다.
    • 목적 레지스터에 저장된 덧셈 결과를 메인 메모리로 전송한다.


프로그램의 구성과 실행

  • 그럼 실제 프로그램의 구성과 실행은 어떻게 될까?
  • 위의 모델을 기반으로 보면 결과를 내기 위해선 데이터와 코드를 불러오고,
    이를 ALU 를 통해 계산을 한뒤 저장을 한다.
    • 모든 프로그램은 결국 데이터 스트림을 가져와서 코드 스트림에 따라 처리하고
      이를 다시 저장하는 과정의 반복이다.

코드 스트림

  • 코드 스트림은 연산 (명령어)의 나열로, 단순 덧셈과 뺄샘 같은 간단한 산술 연산만이 아닌,
    여러 명령어(instruction) 의 순차적 나열로 정의할 수 있다.
    • 이를 프로그램 이라 한다.
  • 명령어는 컴퓨터(ALU 뿐만 아닌 컴퓨터 내부의 모든 유닛)가 어떤 일을 수행할지 지정하는 역할도 한다.

명령어의 종류

  • 산술 명령어
    • ALU 의 특정 산술 연산을 담당
    • add, sub, mul, div 등
  • 메모리 접근 명령어
    • 프로세서와 메인 메모리 사이의 데이터 전송을 담당
    • load, store 등

간단한 프로그램의 예.

  • 아래와 같이 산술/메모리 명령어 포맷이 있을때 프로그램이 실행되는 예이다.
    • 예제에서 #10 은 메모리주소 10을 뜻한다.

산술 명령어 포맷

  • 명령어 소스1, 소스2, 목적
    • add A, B, C // 레지스터 A 와 B 의 값을 더해 C 에 덮어쓴다.

메모리 명령어 포맷

  • 명령어 소스, 목적
    • load #12, A // 메모리셀 #12 의 내용을 레지스터 A 에 읽어온다.

프로그램 예

  • 위의 레지스터를 포함한 문서관리원 모델의 계산기 프로그램은 아래와 같은 작업의 반복이다.
    • load #10, A // 메모리셀 #10 의 내용을 레지스터 A 에 읽어온다.
    • load #11, B // 메모리셀 #11 의 내용을 레지스터 B 에 읽어온다.
    • add A, B, C // 레지스터 A 와 B 의 값을 더해 레지스터 C 에 쓴다.
    • store C, #12 // 덧셈 결과를 레지스터 C 에서 읽어 메모리셀 #12에 쓴다.

program-ex 간단한 덧셈 프로그램의 메모리 예시


메모리 접근

  • 위의 예에서는 프로그래머가 메모리의 어느 위치에 어떤 데이터가 있는지 모두 알아야만 했다.
    • 즉 프로그래머는 모든 메모리 셀의 용도를 미리 정해야만 했다.
  • 실제 프로그램에서는 훨씬 많은 메모리 셀이 존재하므로,
    정확한 메모리 지정이 필요없는 유연한 메모리 접근 방식이 필수적이다.
  • 레지스터값을 메모리 주소로 사용할 수 있게 하면 더 유연한 메모리 접근이 가능하다.

직접값

  • 레지스터 대신 직접적인 값을 사용하는 방식.
    • A 에 있는 값을 2 증가시키기 위해 2 가 저장된 메모리 셀에서
      데이터를 레지스터 B 에 읽어온 후 덧셈을 하는 대신 A 에 2 를 직접 더할 수 있다.
    • add A, 2, A // 레지스터 A 의 값에 직접값인 2 를 더해 기존 A 의 값을 덮어쓴다.

직접값 프로그램 예

  • 레지스터 D 에 주소 #10 이 저장되어 있다고 가정할 때 아래와 같이 프로그램을 만들 수 있다.
    • load #10, D // 메모리셀 #10 의 값(13) 레지스터 D 에 읽어온다.
    • load #D, A // 레지스터 D의 내용(메모리셀 #13의 값)을 레지스터 A 에 읽어온다.
      • 메모리셀 D 의 값에 # 를 붙인 주소값 #13 역시 직접값이다.
    • load #11, B // 메모리셀 #11 의 내용을 레지스터 B 에 읽어온다.
    • add A, B, C // 레지스터 A 와 B 의 값을 더해 레지스터 C 에 쓴다.
    • store C, #12 // 덧셈 결과를 레지스터 C 에서 읽어 메모리셀 #12에 쓴다.

program-ex 메모리 셀에 저장된 주소를 이용해 2개의 수를 더하는 프로그램


상대 레지스터 주소 지정

  • 기본 주소(base address)를 저장하고 있는 레지스터와
    기본 주소에서의 거리를 통해 접근할 메모리 주소로 표현하는 방식.
  • 절대 주소 지정 대신 상대 레지스터 주소 지정을 사용할 경우,
    메모리상에서 데이터의 위치를 정확히 모르는 상태에서도 프로그램을 짤 수 있다.
  • 프로그래머가 운영체제에서 데이터 세그먼트의 기본 주소를 저장하는 곳만 알고 있다면,
    상대 주소를 이용하여 모든 메모리 접근을 지정할 수 있다.
    • 데이터 세그먼트
      • 프로그램의 데이터를 저장하는 연속된 메모리 영역
  • 프로그래머가 데이터 세그먼트의 주소를 안다면, 다음과 같은 방식으로 같은 세그먼트 내의 모든 메모리에 접근이 가능하다.
    • 기본주소 + 오프셋
      • 세그먼트의 기본 주소는 운영체제가 프로그램을 메모리에 로드할 때 정해지고 미리 알 수 없으므로,
        절대 주소 지정방식을 사용할 경우 프로그램 로드시마다 모든 주소값이 변경되어,
        주소계산하는 방식이 매우 복잡해지고 오래 걸릴 수 있다.

상대 레지스터 주소 사용 프로그램 예

  • #D : 메모리 주소 저장을 위한 레지스터, 데이터 세그먼트의 기본 주소를 가지고 있음.
    즉 이 프로그램의 Base 가 되는 주소를 가지고 있다.
    • load #(D + 3), A // 레지스터 D의 내용(메모리셀 #13의 값)을 레지스터 A 에 읽어온다.
    • load #(D + 1 ), B // 메모리셀 #11 의 내용을 레지스터 B 에 읽어온다.
    • add A, B, C // 레지스터 A 와 B 의 값을 더해 레지스터 C 에 쓴다.
    • store C, #(D + 2) // 덧셈 결과를 레지스터 C 에서 읽어 메모리셀 #12에 쓴다.

    program-ex 상대 레지스터 주소를 사용한 프로그램 예


다음 주제

[인사이드 머신] 프로그램 실행의 원리


microprocessor : 컴퓨터의 중앙 처리장치(CPU) 를 뜻한다.