* 들어가는말

 

컴퓨터 시스템의 시작의 마지막 포스팅이다.

 

1장에서는 컴퓨터에 대한 전반적인 이해를 서술하기 때문에 복잡한 면이 있을것이라 생각한다.

 

하지만 시작부터 모든것을 배운다기보다는 그냥 이런게 있다 싶은 정도로만 이해하고 넘어가면 될 듯 하다.

 

나머지 부분은 뒤에서 세세하게 다룰 수 있기 때문이다.

 

8. 네트워크

 

네트워크는 상당히 복잡하다.

 

외부 요인이 상당히 얽혀있고 어느부분이 문제점인지 쉽사리 판별하기 힘든 분야이다.

 

하지만 네트워크 또한 컴퓨터의 입장에서 보면 입출력 장치의 하나로 볼 수 있다.

 

네트워크의 간략화

 

  • 우리가 가진 컴퓨터의 메인메모리에서 바이트 정보를 네트워크를 통하여 전달한다.
  • 네트워크를 통하여 다른 컴퓨터의 메인메모리에 바이트 정보가 복사된다.
  • 이러한 과정이 네트워크이다.

간단하게 살펴보니 네트워크라는 것도 별 어려움이 없다고 생각들지 않는가?

 

컴퓨터가 표현하는 0과 1의 정보를 그저 입출력 장치를 활용하여 복사하여 전달할 뿐이다.

 

우리는 이런 과정을 통하여 e-mail, web 등 많은 서비스를 이용하고 있다.

 

9. Amdahl의 법칙

 

Amdahl 법칙은 다음과 같은 내용을 답고 있다.

 

  • 시스템의 개선은 성능에 얼마나 큰 영향을 미치는가?

이를 위하여 'Gene Amdahl'이 직관적인 계산식을 제시했다.

먼저 정의를 짚고 넘어가보자.

Told : 기존 시스템에서 소요되는 시간

알파 : 개선하고자 하는 것이 전체 시스템에서 담당하는 비율

k : 개선 비율

 

여기서 특정한 부분을 개선한다고 생각하고 계산식을 짚어 넘어가보자.

1. Told * a : 특정 부분이 기존에 소모되는 시간이다.

2. Told * a / k : 개선을 하고 난 뒤의 소모되는 시간이다.

3. Tnew : 아직 개선되지 않은 (1-a)Told와 개선된 a*Told/k를 더한 값이 최종적으로 수정된 소모시간이다.

4. S : Told와 Tnew를 나누어 개선된 비율을 살펴본다.

 

 

여기서 눈여겨 볼 사항은 다음과 같다.

전체 시스템에서 60%의 영향력을 미치는 부분의 성능을 3배 향상시켰다고 가정해보자.

위의 계산식을 이용하면 단지 1.67배 정도의 성능 향상이 이루어졌다.

 

생각보다 큰폭으로 향상되지 않음을 의미한다.

 

즉, 어떠한 시스템의 성능을 대폭 향상시키기는 상당히 어려움을 보여준다고 할 수 있다.

 

10. 동시성과 병렬성

 

성능 개선을 위하여 대표적으로 가지는 특징들이 동시성과 병렬성이다.

 

동시성 : 여러개를 한번에 처리하는 능력

병렬성 : 동시성을 이용하여 빠르게 동작을 수행한다.

 

이는 멀티프로세서 시스템으로 컴퓨터에 구현이 되었으며

최근에는 하이퍼 쓰레딩이라는 기법을 이용하여 성능이 더 좋아졌다.

 

이러한 동시성과 병렬성을 직관적으로 확인할 수 있는것이 윈도우이다.

 

윈도우에서 우리는 웹서핑을 하면서 노래를 듣고 때로는 게임도 틀어놓는다.

 

이렇듯 한 윈도우에서 여러개의 작업이 이루어지도록 하는 것이 동시성과 병렬성의 예시이며, 

컴퓨터 성능에 큰 영향을 미치는 요인이다.

 

 

11. 컴퓨터 시스템의 추상화

 

컴퓨터 시스템에서는 추상화가 매우 중요하다.

 

이는 복잡한 문제를 단순화 시킬 수 있는 도구이다.

 

예를 들자면,

 

우리는 파일을 통하여 입출력장치를 추상화하고,

가상 메모리를 통하여 프로그램 메모리를 추상화하고,

실행중인 프로그램을 통하여 프로세스를 추상화한다.

 

이렇듯 컴퓨터에 있어서 중요한 개념중 하나가 추상화이다.

 

 

12. 정리

우리는 다양한 정보들을 훑어봤다.

 

컴퓨터는 하드웨어와 시스템 소프트 웨어로 구성되었다.

컴퓨터는 정보를 비트들의 그룹으로 표현한다.

컴파일러와 링커를 통하여 실행파일이 생성된다.

컴퓨터는 계층적인 구조를 이루고 있다.

운영체제는 하드웨어와 응용프로그램 사이의 중간자 역할을 수행한다.

 

이제 한번씩 훑어봤으니 좀 더 자세한 컴퓨터의 세계로 나아가보자.

 

 

 

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

1. 컴퓨터 시스템의 시작(2)  (0) 2021.01.04
1. 컴퓨터 시스템의 시작(1)  (0) 2020.12.28

4. hello.exe의 실행 과정

4.1 시스템 H/W 조직에 대한 이해

시스템 H/W는 다양한 컴포넌트들로 이루어져 있다. 시스템의 기본적인 이해를 위하여 각 컴포넌트에 대해서 알아보는 시간을 갖자.

 

  • 버스

컴퓨터 시스템 내의 전기적 배선군이다.

각 컴포넌트 간 바이트 정보를 전송한다.

전송되는 바이트는 워드라는 단위로 전송이 되며, 워드는 시스템의 최소 구성 단위이다.

우리가 알고 있는 32bit, 64bit의 분류 기준이 시스템의 워드 단위를 를 나타낸다.

 

  • 입출력 장치 

시스템과 외부 세계의 상호작용을 담당한다.

마우스, 키보드, 모니터, 디스크 등이 입출력 장치에 해당한다.

디스크에는 우리가 작성한 hello.exe 파일이 저장되어 있다.

 

이 장치는 입출력 버스나 컨트롤러, 어댑터를 통하여 연결되어 있다.

 

  • 메인메모리

프로세서가 프로그램을 실행하는 동안 데이터와 프로그램을 저장하는 장치이다.

메인메모리는 DRAM 칩으로 구성되어 있고, 논리적으로 0부터 시작하는 고유 주소를 가지고 있다.

 

  • 프로세서

프로세서 즉, CPU는 메인메모리에 저장된 인스트럭션의 해독(실행)을 하는 엔진이다.

프로세서의 중심에는 레지스터(워드 크기의 저장장치)와 프로그램 카운터(PC)가 있다.

CPU는 전원이 켜지면 꺼질 때 까지 PC가 가리키는 메모리의 인스트럭션을 반복하며, PC값이 다음 인스트럭션의 위치를 가리키도록 업데이트 하는 역할을 한다.

 

4.2 hello가 실행될 때의 모습

1. 입출력 장치로부터 실행 명령을 받는다.

(마우스로 실행시키거나 ./hello 와 같은 명령어)

2. 파일의 코드와 데이터를 복사하는 인스트럭션이 실행되어 디스크에서 메인 메모리로 이동한다.

3. 프로세서가 main의 기계어 인스트럭션을 실행한다.

4. "hello, world" 문자열은 메모리로 부터 레지스터 파일로 복사된다.

5. 디스플레이 장치로 문자열을 전송하고, 화면에 표시된다.

 

5. 캐시의 중요성

4.2에서 hello가 실행되는 동안의 모습을 살펴보자.

헬로를 실행하면 정보의 이동에 많은 시간이 소요되는 것을 알 수 있다.

(코드와 데이터를 복사하여 디스크에서 메인메모리로 이동, 문자열의 메모리로부터 레지스터 파일로의 복사)

이러한 것들이 앞서서 살펴본 오버헤드에 해당한다고 할 수 있다.

 

즉, 복사과정을 줄이는 것이 시스템의 성능을 올리는 방법이다.

이를 위하여 캐시라는 작은 저장장치를 사용한다.

 

프로세서는 레지스터 파일의 데이터를 읽는데 메모리보다 거의 100배 더 빨리 읽을 수 있다.

하지만 반도체 기술의 발달에 의해 프로세서-메모리간 격차가 지속적으로 증가하고 있다.

메인 메모리보다 프로세서를 향상시키는게 더 쉽고 비용이 적다.

 

이러한 격차를 줄이기 위하여 캐시 메모리라는 것을 고안했다.

캐시는 단기간에 필요로한 임시 저장정보를 저장하는데 사용한다.

또한 캐시는 레지스터 파일만큼 빠른 속도로 액세스 할 수 있는 성능을 가졌다.

 

이 캐시를 활용한다면 자신의 프로그램 성능을 10배 이상 개선할 수 있다.

 

6. 저장장치의 계층 구조

작고 빠른 캐시메모리같은 저장장치를 프로세서와 메인 메모리에 끼워 넣는 개념은 일반적인 아이디어로 여겨진다.

이는 저장장치의 계층구조를 이루는 것과 같은 원리이다.

 

계층 구조의 핵심은 한 레벨의 저장장치가 다음 하위 레벨의 저장장치의 캐시 역할을 한다는 것이다.

 

메모리가 디스크의 캐시 역할을 하는 것과 같은 원리로 말이다.

 

7. 운영체제의 하드웨어 관리.

hello 프로그램에서 입출력 장치를 이용할 때 운영체제가 제공하는 서비스를 활용하였다.

이렇듯 운영체제는 다음과 같은 역할을 한다.

 

  • 응용프로그램의 하드웨어 사용 관리
  • 단순하고 균일한 메커니즘을 통하여 하드웨어 장치의 조작

 

만약 프로그램을 잘못 짜서 하드웨어를 잘못 사용하게 되면 큰일이다. 따라서 운영체제가 이런 일들을 미연에 방지하는 것이다.

 

운영체제는 이와 같은 역할을 근본적인 추상화를 통해 달성하고 있다.

 

  • 가상메모리 - 메인 메모리와 디스크 입출력
  • 파일 - 입출력장치
  • 프로세스 - 프로세서, 메인 메모리, 입출력장치

왼쪽의 요소들이 오른쪽 요소의 추상화를 통하여 나타나는 모습들이다.

 

7.1 프로세스

프로세스는 실행중인 프로그램에 대한 운영체제의 추상화다.

우리는 단 하나의 프로그램만 실행할 수 있는 것이 아니다.

노래를 들으면서 동시에 웹 서핑을 할 수 있다.

이는 프로세서가 프로세스들을 바꿔주는 방식으로 한개의 CPU가 다수의 프로세스를 동시에 실행시키는 것처럼 보여준다.

이를 운영체제에서는 문맥 전환이라는 방법을 사용하여 수행한다.

운영체제는 프로세스가 실행하는데 필요한 모든 상태정보의 변화를 추적하고 ,그것을 컨텍스트라고 한다.

컨텍스트에는 PC, 레지스터 파일, 메인 메모리의 현재 값이 포함되어 있다.

 

7.2 쓰레드

프로세스는 쓰레드라고 하는 다수의 실행 유닛으로 구성되어 있다. 이는 각 쓰레드에서 데이터의 공유가 쉽다는 장점과 프로세스보다 더 효율적이라는 장점을 가지고있다.

 

7.3 가상메모리

각 프로세스에게 부여되는 가상주소 공간이라고 하는 균일한 메모리 공간이다.

스택의 형태를 가지며 위쪽으로 갈수록 주소가 높아진다.

즉 바닥의 주소가 0이 되는 식으로 도식화 한다.

 

7.4 파일

파일은 간단하게 연속된 바이트들을 의미한다.

다만 이는 매우 간단하나 매우 강력하다.

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

1. 컴퓨터 시스템의 시작(3)  (0) 2021.02.01
1. 컴퓨터 시스템의 시작(1)  (0) 2020.12.28

0. 개요

컴퓨터 시스템은 하드웨어와 시스템 소프트웨어 컴포넌트를 가지고 있다.

프로그래머들은 이들 컴포넌트들이 어떻게 동작하고 프로그램 성능과 정확성에 어떤 영향을 주는지 이해해야한다.

컴포넌트란?

독립적인 단위 모듈을 뜻한다. 이는 독립적인 기능을 수핸하며 추후 교체 가능함을 의미한다.
모듈이란?

본체에 대한 독립된 하위 단위를 의미한다.

컴포넌트 vs 모듈

모듈은 정적인 구조를 의미하며, 가장 첫번째, 즉 맨 앞에 위치하는 구현 단위이다.

컴포넌트는 런타임에 독립적으로 배포되고 실행되는 단위이다. 따라서 런타임 개체를 참조한다.



컴포넌트와 모듈의 구분을 가장 쉽게 이해하는 예는 '서버-클라이언트' 구조이다.

컴퓨터 시스템에 서버와 클라이언트 모듈이 존재하고,

하나의 서버에 10개의 클라이언트가 연결된 11개의 컴포넌트를 생각하면 된다.

앞으로 우리는 어떤 내용을 공부하게 될까?

우리는 컴퓨터가 숫자를 표시하는 방법때문에 생기는 이상한 숫자 에러를 피하는 방법 같은 기술을 배우며,

컴파일러가 프로시저 호출을 어떻게 구현하는지,

버퍼 오버플로우의 원리는 어떤것인지,

C코드의 최적화는 어떻게 할 것인지 등에 대해서 공부 한다.

 

 시스템에 관한 공부는 이 다음의 프로그램 부터 시작한다.

#include<stdio.h>

int main(){
	printf("hello, wolrd\n");
    return 0;
}

프로그램이 프로그래머에 의해 만들어지고, 시스템에서 실행되고, 메세지를 출력하고 종료될 때 까지의 수명주기를 추적하는 것으로 부터 시작할 것이다.

 

 

1. 정보의 구성

위의 우리가 작성한 hello.c 소스코드를 살펴보자.

이 소스코드는 0또는 1로 표시되는 비트들의 연속으로 표현되어 있다.

또한 우리가 짠 문자로 표시된 소스코드를 컴퓨터 시스템은 아스키 표준을 사용하여 표현하며,

각 문자를 바이트 길이의 정수값으로 나타낸다.

 

따라서 우리가 작성한 소스코드와 같이 아스키 문자들로만 이루어진 파일들을 텍스트 파일

그 외의 것들은 바이너리 파일이라고 부른다.

 

이 표시방법은 기본 개념에 대해서 확실히 살펴볼 수 있다.

메모리 상 프로그램, 데이터, 네트워크를 통해 전송되는 데이터 등 시스템 정보는 비트들로 표시된다는 것이다.

 

2. 소스코드가 프로그램이 되는 과정

위에서 짠 hello.c를 시스템에서 실행시키려면 C로 짜여진 소스코드를 컴퓨터가 알아들을 수 있도록 기계어 인스트럭션들로 번역해야한다.

인스트럭션(instruction) : 명령어의 집합

이는 실행가능 목적 프로그램으로 합쳐져서 바이너리 디스크 파일로 저장된다.

즉, 컴파일 된다는 의미다.

C를 컴파일 하는 명령어는 대표적으로 다음이 있다.

 

gcc -o hello hello.c

 

gcc 컴파일러의 명령어다.

이 gcc 컴파일러는 소스파일 hello.c를 읽어서 실행파일 hello로 만들어주는 역할을 한다.

그 과정에서 진행되는 단계는 다음과 같다.

 

1. 전처리기

2. 컴파일러

3. 어셈블러

4. 링커

 

* 전처리 단계 : 

소스코드에서 #으로 시작하는 디렉티브(번역 규칙)에 따라 수정한다.

즉 위의 소스코드이 경우 #include<stdio.h> 의 경우 전처리기에 의해서 시스템 헤더파일인 stdio.h를 프로그램 문장에 직접 삽입하라고 지시한다.

즉, 우리가 편의상 #include<stdio.h> 라는 구문을 넣어서 stdio 헤더를 사용했다면 전처리 단계에서는 직접 헤더의 내용들을 소스코드에 변환하여 대입한다는 의미다.

이 과정에서 hello.i 파일이 생성된다.

 

* 컴파일러 :

텍스트 파일인 hello.i 파일을 텍스트 파일인 hello.s 파일로 번역한다.

이 과정에서 어셈블리어 프로그램이 저장된다.

 

* 어셈블러 :

컴파일러가 생성한 hello.s 어셈블리 파일을 기계어 인스트럭션으로 번역하며, 재배치 가능 목적프로그램의 형태로 묶어서 hello.o라는 목적파일을 생성한다.

재배치 가능 이란?

기억장소 내에서 어느 부분이나 자리잡을 수 있는 성질을 의미한다.

* 링커 :

별도의 목적파일에 들어있는 함수들, hello.c의 경우 printf 함수를 호출한다.

즉, 기존에 소스코드에서 필요한 기본 함수들을 연결해주는 과정이다.

따라서 prntf.o 파일에 들어있는 printf 함수를 hello.o 파일과 링크해주는 역할을 하며,

그 결과 실행가능한 목적파일, 즉 실행파일로 메모리에 적재되어 시스템에 의해 실행된다.

 

3. 컴파일 시스템에 이해가 중요한 이유

hello.c처럼 간단한 프로그램의 경우, 컴파일 시스템이 알아서 효율적인 기계어 코드로 만들어 줄 것이다.

하지만 프로그램의 성능 최적화를 위해 기본적인 이해와 컴파일러의 번역 방식은 알 필요가 있다.

이러한 내용들은 다음의 궁금증들을 해결할 것이다.

 

* while과 for 둘중 어떤 것이 효율적일까?

* switch문은 if-else 문을 얼마나 나열할 때 사용하는 것이 좋을까?

* 함수 호출시 발생되는 오버헤드는 얼마나 될까?

* 등등..

오버헤드(overhead) : 어떤 처리를 하기위해 들어가는 간접적인 시간

따라서 우리는 기초적인 컴파일 시스템에 대하여 이해해야한다.

결국 우리가 작성하는 코드를 컴퓨터에게 이해시키는 일은 컴파일러가 하기 때문이다.

 

 

2에서 계속...

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

1. 컴퓨터 시스템의 시작(3)  (0) 2021.02.01
1. 컴퓨터 시스템의 시작(2)  (0) 2021.01.04

+ Recent posts