Search

Chapter 1 : 컴퓨터 시스템으로의 여행

Computer Systems - A Programmer’s Perspective
컴퓨터 시스템 = 하드웨어 + 시스템 소프트웨어

1.1 : 정보는 비트와 컨텍스트로 이루어진다

정보 = 비트 + 컨텍스트
비트 : 컴퓨터가 이해하는 최소 단위의 데이터
컨텍스트 : 비트들이 의미를 갖기 위해 어떻게 해석할 것인지에 대한 문맥
01000001 → 아스키코드 기준(문자 ‘A’), 정수(65), 이미지의 픽셀(색상 정보)
즉, 정보는 의미(컨텍스트)를 가진 데이터(비트)
대부분의 컴퓨터 시스템 : 텍스트 문자를 아스키 표준을 사용해 표시
아스키 표준은 각 문자를 바이트 길이의 정수 값으로 표현
소스 프로그램은 0 또는 1로 표시되는 비트들의 연속
텍스트 파일 : 오로지 아스키 문자들로만 이루어진 파일
사람이 읽을 수 있는 문자로 구성된 파일(.txt, .py, .csv)
소스 코드, 설정 파일, 로그 파일 등
바이너리 파일 : 텍스트 파일 외 다른 파일
사람이 읽기 어려운 이진 데이터로 구성(.exe, .png, .mp3, .pdf, .zip)
멀티미디어, 응용프로그램 실행 파일 등

추가 학습 내용

텍스트 파일과 이미지 파일도 결국 0과 1로 표현될텐데, 그럼 똑같은 비트 내용을 갖더라도 컨텍스트로 인해 다르게 해석되고 다르게 표현되는건가?

맞음. 같은 비트가 문자, 숫자, 픽셀 정보 등으로 표현될 수 있는 것처럼 비트 형태가 동일하다고 정보가 동일하다고 할 수 없음. 비트 형태가 동일해도 문맥(컨텍스트)가 다르기 때문에 다른 결과물로 여겨지는 것

1.2 : 프로그램은 다른 프로그램에 의해 다른 형태로 번역된다

C언어로 작성된 프로그램의 경우, 시스템에서 실행하려면, 각 C문장들은 다른 프로그램들에 의해 저급 기계어 인스트럭션들로 번역됨
인스트럭션들은 실행가능 목적 프로그램(실행가능 목적 파일)이라는 형태로 합쳐짐 → 바이너리 디스크 파일로 저장
컴파일러 드라이버 : 소스파일에서 오브젝트 파일로 번역
4단계
전처리 단계 : 전처리기(ccp)가 C프로그램을 #문자로 시작하는 디렉티브에 따라 수정
.i로 끝나는 새로운 C 프로그램(텍스트 파일) 생성
컴파일 단계 : 컴파일러(ccl)이 어셈블리어 프로그램(.s : 텍스트 파일) 저장
어셈블리 단계 : 어셈블러(as)가 기계어 인스트럭션으로 번역
재배치가능 목적 프로그램 형태로 묶어 목적파일에 저장(바이너리 파일)
링크 단계 : 링커 프로그램(ld)가 통합 작업을 수행
실행 가능 목적파일(실행파일)로 메모리에 적재되어 시스템에 의해 실행

1.3 : 컴파일 시스템이 어떻게 동작하는지 이해하는 것은 중요하다

프로그래머들이 어떻게 컴파일 시스템이 동작하는지 이해해야하는 중요한 이유들 :
프로그램 성능 최적화
링크 에러 이해
보안 약점 피하기 : 버퍼 오버플로우

1.4 : 프로세서는 메모리에 저장된 인스트럭션을 읽고 해석한다

소스 프로그램은 컴파일 시스템에 의해 실행 가능한 목적파일(실행파일)로 번역되어 디스크에 저장
유닉스 시스템에서 실행하기 위해 쉘이라는 응용프로그램에 이름을 입력
쉘 = 커맨드라인 인터프리터

1.4.1 : 시스템의 하드웨어 조직

소스 프로그램을 실행할 때 무슨 일이 일어나는지 설명하기 위해서는 시스템의 하드웨어 조직을 이해해야함
1.
버스
시스템 내를 관통하는 전기적 배선군
컴포넌트들 간에 바이트 정보들을 전송
워드 단위(고정 크기의 바이트 단위)로 데이터를 전송
2.
입출력 장치
시스템과 외부세계와의 연결 담당
EX : 키보드, 마우스, 디스플레이, 디스크 드라이브
각각 입출력 버스 + 컨트롤러(또는 어댑터)를 통해 연결
컨트롤러와 어댑터는 패키징 차이
컨트롤러 : 디바이스 자체가 칩셋이거나 머더보드에 장착됨
어댑터 : 머더보드의 슬롯에 장착되는 카드
둘 다 목적은 입출력 버스와 입출력 장치들 간에 정보를 주고받도록 해주기 위함
3.
메인 메모리
프로세서가 프로그램을 실행하는 동안 데이터와 프로그램을 모두 저장해두는 임시 저장장치
물리적 : DRAM(Dynamic Random Access Memory)들로 구성
논리적 : 연속적인 바이트들의 배열. 각각 0부터 시작해서 고유의 주소(배열의 인덱스)를 보유
4.
프로세서
주저장장치(CPU) : 메인 메모리에 저장된 인스트럭션들을 해독(실행)하는 엔진
PC가 가리키는 곳의 인스트럭션을 반복적으로 실행 + PC값이 다음 인스트럭션의 위치를 가리키도록 업데이트
인스트럭션의 요청으로 CPU가 실행하는 작업들 : 적재(Load), 저장(Store), 작업(Operate), 점프(Jump)
프로그램 카운터(PC)
프로세서 중심부 위치
워드 크기의 저장장치(또는 레지스터)
특정 순간에 PC는 메모리의 기계어 인스트럭션을 가리킴
레지스터 파일
각각 고유의 이름을 갖는, 워드 크기의 레지스터 집합으로 구성
ALU(산술논리연산장치)
새 데이터와 주소 값을 계산

1.4.2 : hello 프로그램의 실행

쉘 프로그램으로 실행하는 C 소스코드
쉘 프로그램이 사용자 입력을 통해 받은 각 문자를 레지스터에 읽어들인 후, 메모리에 저장
파일 내의 코드와 데이터를 복사하는 일련의 인스트럭션을 실행하여 실행 파일을 디스크에서 메인 메모리로 로딩
데이터는 직접 메모리 접근(DMA) 기법을 통해 프로세서를 거치지 않고 디스크에서 메인 메모리로 직접 이동
목적파일(실행파일)의 코드 & 데이터가 메모리에 적재된 후, 프로세서는 기계어 인스트럭션을 실행하기 시작
내용을 메모리로부터 레지스터 파일로 복사하고, 디스플레이(입출력 장치)로 전송해 글자 표시

1.5 : 캐시가 중요하다

시스템이 정보를 한 곳에서 다른 곳으로 이동시키는 일에 많은 시간을 보냄
EX : 프로그램의 기계어 인스트럭션들
하드디스크에 저장
프로그램이 로딩될 때, 메인 메모리로 복사
이러한 복사 과정은, 프로그램의 실제 작업을 느리게 하는 오버헤드
캐시 메모리(캐시) : 작고 빠른 저장장치
지역성 : 프로그램이 지엽적인 영역의 코드 및 데이터를 액세스하는 경향
캐시를 활용해 자신의 프로그램 성능을 10배 이상 개선 가능!

1.6 : 저장장치들은 계층구조를 이룬다

모든 컴퓨터 시스템의 저장장치들은, 메모리 계층 구조를 이룸
상위 계층 : 작음, 바이트 당 가격 비쌈, 빠름
레지스터
캐시 메모리(캐시)
L1
L2
L3
메인 메모리
로컬 디스크
원격 디스크
하위 계층 : 큼, 바이트 당 가격 저렴, 느림
메모리 계층구조의 주요 아이디어 : 한 레벨의 저장장치가 다음 하위레벨 저장장치의 캐시 역할을 담당!!

1.7 : 운영체제는 하드웨어를 관리한다

프로그램이 여러 장치에 직접 액세스하지 않음
운영체제가 제공하는 서비스를 활용
운영체제
하드웨어와 소프트웨어 사이에 위치한 소프트웨어 계층
응용프로그램이 하드웨어를 제어하려면, 언제나 OS를 통해야함
두 가지 주요 목적
1.
응용 프로그램들이 하드웨어를 잘못 사용하는 것을 막기 위함
2.
응용프로그램들이 단순하고 균일한 매커니즘을 사용하여 저수준 하드웨어 장치들을 조작할 수 있도록 하기 위함
2가지 목표를 추상화를 통해 달성
1.
프로세스 : 프로세서, 메모리, 입출력 장치 추상화
2.
가상메모리 : 메모리와 디스크 입출력 장치 추상화
3.
파일 : 입출력 장치 추상화

1.7.1 : 프로세스

OS는 시스템에서 한 개의 프로그램만 실행되는 것 같은 착각에 빠지도록 함
프로세스에 의해 착각처럼 느껴지는 것
프로세스 : 실행 중인 프로그램에 대한 운영체제의 추상화
다수의 프로세스들은 동일한 시스템에서 동시에 실행 가능
프로세서가 프로세스들을 바꿔주는 방식으로 한 개의 CPU가 다수의 프로세스를 동시에 실행하는 것처럼 보이게 함
OS는 문맥전환을 통해 교차실행을 수행
OS는 프로세스가 실행하는 데 필요한 모든 상태정보의 변화를 추적
컨텍스트(상태정보) : 프로그램 카운터, 레지스터 파일, 메인 메모리의 현재 값을 포함
커널문맥전환(하나의 프로세스에서 다른 프로세스로의 전환)을 관리
커널 : 운영체제 코드 일부, 메모리에 상주
응용프로그램이 작업 요청 → 컴퓨터가 특정 시스템 콜을 실행하여 커널에게 제어를 넘김 → 커널은 요청된 작업을 수행하고 프로그램에게 리턴
유의사항 : 커널은 별도의 프로세스가 아님
모든 프로세스를 관리하기 위해 시스템이 이용하는 코드와 자료구조 집합

1.7.2 : 쓰레드(Thread)

최근 시스템에서 프로세스는 실제로 쓰레드라고 하는 다수의 실행 유닛으로 구성됨
각 쓰레드 : 해당 프로세스의 컨텍스트에서 실행
동일 코드 & 전역 데이터를 공유
여러 프로세스를 사용하는 것보다 데이터 공유가 쉽고, 쓰레드가 프로세스보다 효율적

1.7.3 : 가상메모리

가상메모리 : 각 프로세스들이 메인 메모리 전체를 독점적으로 사용하고 있는 듯한 환상을 제공하는 추상화
각 프로세스 → 가상주소공간이라고 하는 균일한 메모리의 모습을 가짐
가상주소공간은 몇 개의 정의된 영역으로 구성
커널 가상메모리 영역(최상위 주소)
주소공간의 맨 윗부분
커널을 위해 예약된 주소
스택 영역
(사용자 가상메모리 공간 맨 위에) 컴파일러가 함수 호출을 구현하기 위해 사용하는 공간
동적으로 크기가 변함
함수를 호출할 때마다 크기 증가 / 함수에서 리턴할 때는 크기 감소
공유 라이브러리 영역
공유 라이브러리의 코드와 데이터를 저장하는 영역
힙 영역
런타임에 동적으로 크기가 변하는 공간
프로그램 및 데이터 영역(최하위 주소)
실행가능 목적파일로부터 직접 초기화됨

1.7.4 : 파일

파일 = 연속된 바이트들
모든 입출력장치(EX : 디스크, 키보드, 디스플레이, 네트워크)는 파일로 모델링
시스템의 모든 입출력은 유닉스I/O라는 시스템 콜들을 이용해 파일을 읽고 쓰는 형태로 이뤄짐

추가 학습 내용

정확히 문맥 전환(Context Switch)란 시스템 내부에서 어떤 작업을 말하는걸까?

문맥 : 프로세스의 상태 정보 전부(= PC, 레지스터 값, 스택 포인터 등)
문맥전환이 발생하는 상황:
CPU가 현재 프로세스를 멈추고 다른 프로세스를 실행할 때
인터럽트 처리 중 다른 작업으로 넘어갈 때
시스템 콜 요청으로 커널 모드 전환
문맥전환 발생 시, 커널이 수행하는 작업
1.
현재 실행 중인 프로세스의 상태 저장
2.
새로운 프로세스의 상태 복원
3.
CPU 제어권 반환
이러한 작업들은 하드웨어 레벨 제어이므로, 보안과 안정성을 위해 응용 프로그램이 제어하지 않고, 커널이 관리함
즉, 현재 실행 중인 프로세스의 상태를 저장하고 다음에 실행할 프로세스의 상태를 복원해서 CPU 실행 흐름을 전환하는 책임을 커널이 짐

1.8 : 시스템은 다른 시스템과 네트워크를 사용하여 통신한다

(시스템 = HW + SW) → 하나의 분리된 집합체
최신 시스템들은 네트워크를 통해 다른 시스템과 연결
네트워크 = 또 다른 입출력장치로 취급 가능
시스템이 메인 메모리로부터 네트워크 어댑터로 입련의 바이트(파일 = 연속된 바이트들)를 복사할 때, 데이터는 로컬디스크 드라이브 대신 네트워크를 통해 다른 컴퓨터로 이동

1.9 : 중요한 주제들

1.9.1 : Amdahl의 법칙

우리가 어떤 시스템의 한 부분의 성능을 개선할 때, 전체 시스템 성능에 대한 효과는 그 부분이 얼마나 중요한가와 이 부분이 얼마나 빨라졌는가에 관계됨
Told = 응용프로그램을 실행하는 데 걸리는 시간, 시스템의 어떤 부분이 시간의 a비율 만큼을 소모, 이것의 성능을 k배 개선하려함.
즉, 이 컴포넌트는 원래 aTold만큼 시간을 요구하고, 이제 (aTold)/k 시간을 요구함
Tnew=시스템나머지부분실행시간+개선시간=(1a)Told+(aTold)/k=Told[(1a)+a/k)]Tnew = 시스템 나머지 부분 실행 시간 + 개선시간 = (1-a)Told + (aTold)/k = Told[(1-a) + a/k)]
S(개선된속도)=1/[(1a)+a/k]S(개선된 속도) = 1/[(1-a) + a/k]
주요 통찰 : 전체 시스템을 상당히 빠르게 하기 위해서는 전체 시스템의 매우 큰 부분의 성능을 개선해야함
시스템의 60%를 차지하는 컴포넌트의 성능을 무한대로 개선한다면?
k는 무한대 → 그래봐야 2.5배 개선됨
즉, 일상적으로 우리가 성능을 2배 이상 개선할 수 있다는 건 컴퓨터 세계에서 엄청난 의미 가짐
시스템의 많은 부분을 최적화해야 높은 배율을 얻을 수 있음

1.9.2 : 동시성과 병렬성

동시성 : 다수의 동시에 벌어지는 일을 갖는 시스템에 관한 일반적인 개념을 말할 때
병렬성 : 동시성을 사용해서 시스템을 보다 빠르게 동작하도록 하는 것을 말할 때

쓰레드 수준 동시성

단일 프로세서 시스템
다수의 프로그램이 동시에 실행되는 시스템(프로세스 추상화 개념) → 동시성 개념으로 이어짐
쓰레드 이용 → 한 개의 프로세스 내에서 실행되는 다수의 흐름 제어를 획득 가능
시간 공유 기법 → 동시 실행에 대한 지원이 컴퓨터 시스템에 나타남
한 개의 컴퓨터가 실행하는 프로세스를 빠르게 전환하는 방법
멀티프로세서 시스템
시스템이 여러 개의 프로세서를 가지고 하나의 운영체제 커널의 제어 하에 동작하는 경우
최근 멀티코어 프로세서들과 하이퍼쓰레딩 기법의 출현으로 보다 일반적인 환경이 됨
하이퍼쓰레딩(멀티쓰레딩) : 하나의 CPU가 여러 개의 제어 흐름을 실행할 수 있게 해주는 기술
멀티프로세싱은 CPU를 여러 개 사용하는 만큼 하드웨어 성능이 좋아졌지만, 그만큼 성능이 좋아지려면 프로그램도 멀티쓰레딩으로 잘 작성해야함

인스트럭션 수준 병렬성

최근 프로세서들은 훨씬 낮은 수준의 추상화로, 여러 개의 인스트럭션을 한 번에 실행 가능해짐
한 인스트럭션을 실행하는 데 필요한 클럭 수가 줄었음
파이프라이닝 기법을 통해 더 많은 인스트럭션을 한 번에 처리할 수 있게 됨
슈퍼스케일러
한 개 이상의 인스트럭션을 실행할 수 있는 프로세서
최근 프로세서들은 슈퍼스케일러 동작을 지원

싱글 인스트럭션, 다중 데이터 병렬성(SIMD)

SingleInsturction, MultipleData : 하나의 명령어로 여러 데이터 동시 처리 가능
EX : a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]
똑같은 연산을 여러 데이터 상에 반복해야하는 상황에서, 명령어를 4번 사용하는게 아니라 한 번에 모두 처리하는 방식
최하위 수준 : CPU 내부에 존재하는 HW레벨의 기능
데이터 병렬성(같은 연산을 여러 데이터에 반복할 때)에 효과적

추가 학습 내용

동시성과 병렬성이란?

동시성
하나의 CPU가 여러 작업을 번갈아가며 처리하는 것
시간을 쪼개어 여러 작업을 처리하는 것처럼 보이게 하는 기술
작업들을 빠르게 전환(Context Switch)하면서 마치 동시에 하는 것처럼 보이게
병렬성
여러 개의 CPU가 여러 작업을 진짜 동시에 처리하는 것
CPU 코어나 프로세스가 둘 이상이여야 가능(= 물리적으로 여러 작업을 동시 수행)

1.9.3 : 컴퓨터 시스템에서 추상화의 중요성

추상화 : 전산학에서 가장 중요한 개념
EX : 함수들을 간단한 응용프로그램 인터페이스 API로 정형화하는 것 → 이를 통해 내부 동작은 고려하지 않고 코드를 사용할 수 있도록 함
운영체제 측면에서의 추상화
파일 : 입출력 장치 추상화
가상메모리 : 프로그램 메모리(메인 메모리 + 디스크) 추상화
프로세스 : 실행 중인 프로그램(프로세서 + 메인 메모리 + 입출력 장치) 추상화
가상머신 : 컴퓨터 전체 추상화

1.10 : 요약

(컴퓨터 시스템 = HW + SW) 구성 ← 응용프로그램을 실행하기 위해
컴퓨터 내 정보 : 상황에 따라 다르게 해석되는 비트들의 그룹으로 표시
시스템의 저장장치들 : 계층구조를 형성
계층구조 상부의 저장장치 : 하부 장치들을 위한 캐시 역할 수행
운영체제 커널
응용프로그램과 하드웨어 사이에서 중간자 역할
세 가지 근본적인 추상화 제공
파일 : 입출력장치 추상화
가상메모리 : 메인 메모리와 디스크 추상화
프로세스 : 프로세서, 메인 메모리, 입출력 장치 추상화
네트워크
컴퓨터 시스템이 서로 통신할 수 있는 방법 제공
특정 시스템 관점에서, 네트워크는 단지 또 하나의 입출력장치일 뿐!