ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컴퓨터의 동작 원리
    Computer Science 2021. 10. 28. 23:02

     

    컴퓨터의 기본 구조

    컴퓨터의 핵심 부품에는 프로세서와 메모리가 있다. 메모리(RAM)는 컴퓨터가 수행해야 할 명령어를 써넣는 공간이다. 추가적으로 연산의 대상이 되는 데이터도 저장된다. 프로세서(CPU)는 메모리에서 명령어와 데이터를 읽어 그에 맞게 계산하는 부품이다.

     


     

    메모리

    메모리는 수많은 셀로 나뉘어 있다. 각 셀은 미세한 양의 데이터를 저장한다. 셀을 구별하기 위한 주소 번호가 순서대로 매겨져 있다. 데이터를 읽고 쓰는 작업은 셀을 한 번에 하나씩 조작하는 연산을 통해 수행한다. 셀의 주소 번호를 통해 특정 셀에 접근하여 읽기(값 구하기), 쓰기(새 값 저장) 작업을 수행할 수 있다. 

     

    메모리는 전기 부품이므로, 주소는 전선을 통해 이진수로 전송한다. 높은 전압이 걸린 전선은 '1'신호를, 낮은 전압은 '0' 신호를 나타낸다.

     

     

    메모리에는 읽기, 쓰기 중 어느 동작을 수행할 것인지 설정하는 특별한 입력 전선이 있다.

     

     

    일반적으로 셀 하나에 여덟 자리 이진수인 1Byte를 저장할 수 있다. '읽기' 모드에서 셀에 저장된 바이트를 여덟 가닥의 데이터 전선으로 출력한다. '쓰기' 모드일 때는 그 전선들을 통해 바이트를 읽어 들여 지시된 셀에 써넣는다.

     

     

     

    한 덩어리의 데이터를 전송하는 전선의 모음을 버스bus라고 한다. 주소를 전송하는 데 사용되는 여덟 가닥의 전선은 주소 버스를 구성한다. 마찬가지로, 메모리 셀과 데이터를 주고받는 데 사용되는 다른 여덟 가닥의 전선은 데이터 버스를 구성한다. 주소 버스는 단방향이고 데이터 버스는 양방향이다.

     

    컴퓨터의 CPU와 RAM은 끊임없이 데이터를 교환한다. CPU는 메모리에서 명령어와 데이터를 지속적으로 읽어 들이며, 출력 값이나 중간 계산을 메모리에 저장하기도 한다. 

     

     


     

    CPU

    CPU 내부에는 레지스터register 라고 불리는 CPU 자체의 메모리 셀들이 있다. 레지스터에 저장된 수를 대상으로 간단한 연산을 수행할 수 있다. 또, RAM과 레지스터 사이에서 데이터를 교환할 수도 있다. 다음은 CPU가 수행하는 명령의 전형적인 예이다.

      - 메모리 220번 셀의 데이터를 레지스터 3번으로 복사하라

      - 레지스터 3번의 수를 레지스터 1번의 수에 더하라

     

    CPU가 수행할 수 있는 모든 연산의 집합을 명령어 집합instruction set이라고 한다. 명령어 집합의 각 연산에는 번호가 할당되어 있다. 컴퓨터 프로그램 코드는 근본적으로 CPU의 연산을 나타내는 번호들을 실행 순서에 따라 배열한 것이다. 프로그램은 실행할 때 이 연산(번호)들은 수로서 RAM에 저장된다. 

    입출력 데이터, 중간 계산 데이터, 프로그램 코드 등이 모두 RAM에 뒤섞여 저장된다.

     

    CPU의 동작은 메모리의 명령어를 끊임없이 가져와 수행하는 무한 루프로 이루어진다. 이 주기의 중심에는 프로그램 카운터program counter가 있다. PC는 다음에 수행해야 할 명령어가 기록된 메모리의 주소를 가리키는 특별한 레지스터다. CPU는 PC를 활용하여 다음과 같은 과정을 거쳐 명령을 수행한다.

      - PC가 가리키는 메모리 주소에서 명령어를 가져온다

      - PC를 1 증가시킨다

      - 가져온 명령어를 수행한다

      - 1단계로 돌아간다

     

    CPU에 전원을 넣으면 PC가 기본값으로 설정된다. 이 값은 기계가 수행해야 할 첫 번째 명령어가 저장된 주소이다. CPU는 명령어를 가져오고 실행하는 과정을 반복하며, 이 과정이 한 번 수행되는 것을 주기cycle라고 한다.

     

    위의 과정대로라면 CPU는 그저 PC를 단순히 1씩 증가시키기만 할 것이다. 그저 연산 목록을 순서대로 따를 수만 있을 것이다. 그래서 점프라는 명령도 지원한다. PC에 새로운 값을 넣어 실행 흐름을 다른 지점으로 건너뛰도록 하는 명령이다. 이 분기를 조건부로 처리할 수도 있다.

     

    if x = 0
        compute_this()
    else
        compute_that()

     

     

    이런 단순한 연산들을 모으면 복잡한 프로시저도 표현할 수 있다. 여러 개의 프로시저를 조합하여 프로그램을 구성하므로, 프로그램은 결국 단순한 연산들을 모아 나열한 것이다.   

     

     

    CPU Clock

    클락이란 CPU가 1초 동안 실행하는 기본 연산이 몇 개인지를 나타내는 단위이다. 2메가 헤르츠의 클락이면 CPU가 1초에 약 2백만 개의 기본 연산을 수행한다는 뜻이다. 

     

    오늘날에는 평범한 데스크톱이나 스마트폰에도 흔히 2기가 헤르츠 GHz 가량의 CPU가 탑재된다. 최근에는 멀티 코어 CPU가 대거 채택되고 있다. 

     

     

    CPU 아키텍처

    플레이스테이션 CD를 컴퓨터에 넣으면 게임이 실행되지 않는다. 서로 CPU 아키텍처(구조)가 다르기 때문이다. CPU 아키텍처가 다르다는 것은 CPU 명령어 집합이 다르며, 따라서 명령어에 숫자 번호를 매기는 방법도 다르다는 것을 뜻한다. 요즘의 개인용 컴퓨터는 대부분 x86 아키텍처를 사용한다

     

     

    리틀 엔디언과 빅 엔디언

    RAM과 CPU에 수를 왼쪽에서 오른쪽 순으로 저장하는 방식은 리틀 엔디언little-endian이라고 하며 오른쪽에서 왼쪽 순으로 저장하는 방식은 빅 엔디언big-endian이라고 한다.

     

    1-0-0-0-0-0-1-1 이진 수열을 예로 들면, 어느 엔디언에 따라 배열되었느냐에 의해 나타내는 수가 다르다.

      - 빅 엔디언 : 2^7 + 2^1 + 2^0 = 131

      - 리틀 엔디언 : 2^0 + 2^6 + 2^7 = 193

     

    초창기 네트워크 중계기의 대부분은 빅 엔디언을 사용했고, 오늘날 대부분의 CPU는 리틀 엔디언 방식이다. 리틀 엔디언으로 생성된 데이터를 빅 엔디언으로 해석하려면 엔디언 불일치 endianness mismatch를 해결하기 위한 조치가 필요하다. 

     

     

    에뮬레이터

    다른 컴퓨터를 위해 설계된 코드를 실행하고 싶을 때, 예를 들어 아이폰 없이 아이폰 앱을 테스트하고 싶을 때 에뮬레이터 emulator라는 소프트웨어가 필요하다.

     

    에뮬레이터는 목표로 하는 기계를 흉내 내는 가상 프로그램이다.

     


     

    컴파일러

    사람의 손으로 CPU 명령어를 짜는 것은 비효율적이다. 컴파일러compiler를 사용하여 프로그래밍 언어를 CPU가 실행할 수 있는 기계어 명령어로 번역한다. 복잡한 고수준 프로그래밍 언어로 작성된 프로그램은 단순한 저수준 프로그래밍 언어(기계어)로 번역해주는 프로그램이다.

     

     

    스크립트 언어

    컴파일하지 않고도 실행할 수 있는 프로그래밍 언어를 스크립트 언어라고 한다. 자바스크립트 파이썬 등이 이에 해당한다. 코드를 CPU가 직접 실행하는 것이 아니라 인터프리터interpreter(해석기)를 통해 실행한다. 따라서 코드가 실행되려면 컴퓨터에 인터프리터가 설치되어 있어야 한다. 

    일반적으로 스크립트 언어는 컴파일된 코드에 비해 훨씬 느리다. 

     

     

    역어셈블리와 역공학

    현재까지는 한번 컴파일러된 프로그램을 컴파일 이전의 소스코드로 되돌리는 것을 불가능하다. 하지만 이진 프로그램의 기계어 코드 배열을, 사람이 읽을 수 있는 명령어의 배열로 변환하는 것은 어렵지 않다. 이것은 역어셈블리disassembly라고 한다.

     

    이렇게 이진수 코드를 명령어 코드로 변환한 후에는, 이 기계어들을 읽어 무슨 작업을 하는 것인지 조사할 수 있다. 이를 역공학reverse engineering이라고 한다. 역어셈블리 프로그램 중에는 시스템 호출과 자주 사용되는 함수를 자동으로 탐지해 표시해주는 것도 있다. 

     

    해커들은 윈도우, 포토샵처럼 사용권이 제한된 프로그램의 이진 코드를 분석해 사용권 검사 코드를 찾아낸다. 그러고는 사용권 검사 코드의 위치에 사용권 인증 후 실행될 코드로 바로 건너뛰도록 하는 JUMP 명령을 배치한다. 이렇게 조작된 이진 코드에서는 사용권을 검사하기도 전에 JUMP 명령이 실행된다.

     


     

    메모리 계층 구조

    컴퓨터는 CPU가 간단한 명령어를 실행하기만 해도 동작하다. 이 명령어들은 CPU 레지스터에 저장된 데이터만을 연산할 수 있다. 하지만 레지스터는 용량이 작다. 그러므로 RAM과 끊임없이 데이터를 주고받아야 한다. 따라서 메모리에 접근하는 속도는 컴퓨터의 성능에 직접적인 영향을 미친다. CPU가 레지스터의 데이터에 접근하는 데 걸리는 시간은 한 주기 이내로 '순식간에' 이루어진다. 반면에 RAM은 '훨씬' 느리다.

     

     

    프로세스-메모리 격차

    최근까지 CPU 속도는 매우 빠르게 '지수적으로' 증가했다. 메모리의 속도는 상대적으로 증가율이 훨씬 낮다. 이런 이유로 CPU는 저렴하고, RAM은 비싸다. CPU와 메모리의 성능 차이를 프로세서-메모리 격차라고 한다. 이 격차가 벌어질수록 메모리에 효율적으로 접근하는 것이 더욱 중요해진다.

     

     

    시간-공간 인접 주소

    RAM 접근 횟수를 최소화하는 방법을 연구하던 학자들은 다음과 같은 두 가지 사실을 깨닫는다.

     

      - 시간 인접 주소 temporal locality : 어떤 메모리 주소에 접근한 경우, 잠시 후 같은 주소에 다시 접근할 가능성이 높다. 

      - 공간 인접 주소 spatial locality : 어떤 메모리 주소에 접근한 경우, 잠시 후 인접한 주소에 접근할 가능성이 높다.

     

    이 경험을 토대로 주소를 예측하여 레지스터에 저장해 둔다면 RAM 접근 연산을 줄일 수 있다. 그러나 레지스터의 용량을 높이는 데엔 한계가 있다. 그럼에도 시공간 인접 주소를 효율적으로 탐색할 수 있는 방법들이 발견되었다.

     

     

    1차 캐시 

    : 레지스터의 용량을 늘리지 못하더라도, CPU와 통합된 빠른 보조 메모리를 만드는 것은 가능하다. 이를 1차 캐시 L1 cache라고 한다. 1차 캐시를 활용하면, 접근 가능성이 높은 메모리 주소의 내용을 레지스터 가까이에 복사해 둘 수 있다. 1차 캐시의 데이터를 레지스터로 옮기는 데 약 10 cpu 주기밖에 걸리지 않는다.(데이터를 RAM에서 가져올 때보다 백 배 정도 빠르다.)

     

     

    2차 캐시

    : 1차 캐시의 용량이 약 50킬로바이트를 넘어가면 용량을 증설하는 비용이 매우 높아진다. 그보다는 메모리 캐시를 한 단계 더 추가하는 2차 캐시 L2 cache를 사용하는 것이 더 효율적이다. 2차 캐시는 속도가 좀 더 느려고 되므로 더 큰 용량으로 만들 수 있다. 오늘날의 CPU에는 200킬로바이트 정도가 탑재된다. CPU 레지스터로 옮기는 데는 약 1백 CPU 주기가 든다.

    접근 가능성이 가장 높은 주소는 1차 캐시에 복사된다. 그다음으로 접근 가능성이 높은 메모리 공간은 2차 캐시에 복사된다. 두 캐시 모두에 데이터가 없을 때만 RAM에 직접 접근한다. 

    CPU에서 1, 2, 3차 캐시는 매우 중요하다. CPU의 물리적 공간의 대부분을 차지한다. CPU의 클락이 좀 낮더라도 캐시 용량이 큰 게 더 나은 경우도 있다. 

     

     

    1차 메모리와 2차 메모리

    메모리들은 속도, 용량, 비용에 따라 계층 구조를 형성한다. 꼭대기 계층의 메모리는 속도가 가장 빠르지만 용량이 적고 매우 비싸다. 

     

     

     

    'Computer Science' 카테고리의 다른 글

    OSI 7 Layer와 TCP/IP Protocol  (0) 2021.11.10
    프로그래밍 기법과 패러다임 종류  (0) 2021.10.30
    컴파일러 언어vs 인터프리터 언어  (0) 2021.05.09
    Home server  (0) 2021.04.10
    문자와 문자열  (0) 2021.03.03
Designed by Tistory.