컴퓨터 시스템은 하드웨어와 시스템 소프트웨어로 구성되며, 이들이 함께 동작해 응용프로그램을 실행한다. 시스템의 구현방법은 시간에 따라 바뀔 수 있지만, 근본적인 개념들은 변하지 않는다.
// hello.c
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
작성한 글자는 컴파일러나 시스템에 의해 ASCII 코드 등의 숫자로 변환되고, 그 숫자는 비트(0과 1)로 바뀌어 메모리와 저장장치에 기록된다.
이런 변환은 모든 텍스트 처리의 기본 과정이며, 컴퓨터 시스템이 텍스트를 이해하고 처리하는 방식이다.
컴퓨터가 "글자를 이해한다."는 말의 실질적인 의미다.
linux> gcc -hello hello.c
C 소스 파일 hello.c가 최종적으로 실행 가능한 프로그램 hello로 변환되기까지는 단순한 비트 변환 그 이상으로, 여러 단계의 번역 과정을 거친다. 이 과정을 GCC 컴파일러 드라이버가 관리하며, 일반적으로 다음의 4단계를 거친다.

1. 전처리 (Preprocessing)
전처리기(cpp)는 본래의 C 프로그램을#문자로 시작하는 디렉티브(directive)에 따라 수정한다.
#include<stdio.h>는 전처리기에 시스템 헤더파일인 stdio.h를 프로그램 문장에 직접 삽입을 지시한다.#define PI 3.14는 PI를 3.14로 치환하는 매크로를 정의한다.2. 컴파일 (Compilation)
컴파일러(cc1)는 텍스트파일 hello.i를 텍스트파일인 hello.s로 번역한다.
main 함수는 프로그램의 시작점(entry point) 역할을 하므로, 정의가 없다면 실행 가능한 코드가 생성되지 않는다.3. 어셈블 (Assembly)
어셈블러(as)가 hello.s를 기계어 인스트럭션으로 번역하고, 이들을 재배치가능 목적프로그램의 형태로 묶어서 hello.o라는 목적파일에 그 결과를 저장한다.
main 함수의 인스트럭션들을 인코딩하기 위한 17바이트를 포함하는 바이너리 파일이다.hello.o 파일을 텍스트 편집기로 열어보면 쓰레기 같은 데이터로 보일 것이다.4. 링크 (Linking)
printf 처럼 다른 파일이나 라이브러리에 정의된 함수들을 프로그램에 붙여서 실행 가능하게 만드는 과정이다.
hello.o 안에 printf를 사용한 흔적이 있음.libc 또는 libc.a, libc.so 같은 표준 라이브러리 파일을 뒤져서 printf의 구현을 찾음.main도 있고, printf도 있게됨.컴파일 시스템은 hello라는 실행 파일을 생성해 디스크에 저장하며, 이 파일은 쉘을 통해 실행할 수 있다.
linux> ./hello
hello, world
linux>

시스템 내를 관통하는 전기적 배선군을 버스라고 하며, 컴포넌트들 간에 바이트 정보들을 전송한다. 일반적으로 워드(word)라고 하는 고정 크기의 바이트 단위로 데이터를 전송하도록 설계된다.
32bit OS: 4Byte, 64bit OS: 8Byte의 워드 크기를 가진다.
시스템과 외부 세계와의 연결을 담당한다. 키보드와 마우스, 디스플레이, 디스크 드라이브 등이 I/O 버스에 연결되어 정보를 주고 받는다.
프로세서가 프로그램을 실행하는 동안 데이터와 프로그램을 모두 저장하는 임시 저장장치다. 물리적으로 메인 메모리는 DRAM(Dynamic Random Access Memory) 칩들로 구성돼 있고, 논리적으로 메모리는 연속적인 바이트들의 배열로, 각각 0부터 시작해서 고유의 주소(배열의 인덱스)를 가지고 있다.
주처리장치(CPU)또는 간단히 프로세서는 메모리에 저장된 기계어 명령(인스트럭션)을 하나씩 읽고 실행하는 장치다. 이 과정을 전원이 꺼질 때까지 반복한다.
[인스트럭션 읽기] → [해석하고 실행] → [다음 인스트럭션 주소로 이동] → (반복)
인스트럭션 요청에 의해 CPU가 실행하는 단순한 작업의 예
적재(Load) -> 작업(Operate) -> 저장(Store) -> 점프(Jump)
메인 메모리에서 레지스터에 한 Byte 또는 Word를 이전 값에 덮어쓰는 방식으로 복사한다.
두 레지스터의 값을 ALU로 복사하고 두 개의 워드로 수식연산을 수행한 뒤, 결과를 덮어쓰기 방식으로 레지스터에 저장한다.
레지스터에서 메인 메모리로 한 Byte 또는 Word를 이전 값을 덮어쓰는 방식으로 복사한다.
인스트럭션 자신으로부터 한 개의 Word를 추출하고, 이것을 PC에 덮어쓰기 방식으로 복사한다.
if (a + b > 10) x = 1;
a, b 값을 메모리에서 가져온다.a + b 계산x = 1 결과를 메모리에 저장캐시는 메인 메모리보다 훨씬 빠른 임시 저장소이며, CPU가 데이터를 훨씬 빠르게 접근할 수 있도록 도와준다.
CPU(프로세서)는 빠르게 발전하지만, 메모리는 상대적으로 느리게 발전하고 있다.
그래서 캐시가 중요하다.
지역성 원리 활용
프로그램은 일반적으로 최근에 참조했던 데이터나 코드, 그리고 그 주변의 데이터나 코드를 다시 참조하는 경향이 있다. 캐시는 이러한 지역성 원리를 활용하여 자주 사용될 것으로 예상되는 데이터나 명령어를 빠른 캐시 메모리에 미리 가져다 놓음으로써, 프로세서가 필요로 하는 데이터를 빠르게 찾을 확률을 높입니다.
캐시의 성능은 전체 시스템 속도를 좌우하는 핵심적인 요소다. 프로세서가 캐시에서 필요한 데이터를 빠르게 찾을 수 있다면, 메인 메모리나 디스크까지 접근할 필요 없이 빠르게 작업을 계속할 수 있어 프로그램 실행 속도가 크게 향상된다.
결론적으로 캐시는 프로세서와 주 저장장치 사이의 치명적인 속도 차이를 효과적으로 완화하고, 프로그램의 지역성 원리를 활용하여 데이터 접근 속도를 비약적으로 높이기 때문에 컴퓨터 시스템 성능 향상에 있어 매우 중요하다.

컴퓨터 시스템의 저장장치는 속도와 비용에 따라 여러 단계의 계층 구조를 이룬다. 레지스터, 캐시(L1, L2, L3), 주기억장치(메인 메모리), 디스크 저장소 등이 포함된다. 계층 구조에서 더 빠르고 작은 저장장치는 느리고 큰 저장장치보다 상위에 위치한다.
캐싱의 기본적인 역할은 자주 사용되는 데이터를 느린 저장장치에서 더 빠른 저장장치로 가져와 임시로 보관하는 것이다. 이를 통해 프로세서가 데이터를 필요로 할 때 느린 저장장치까지 가지 않고 빠른 캐시에서 데이터를 바로 얻을 확률(Cache Hits)을 높여 전반적인 성능을 향상시킨다.
다른 시스템의 디스크에 저장된 데이터(L6)는 로컬 시스템의 관점에서는 느린 원격 저장소에 있는 데이터다. 로컬 디스크(L5)는 이 원격 저장소보다 빠르므로, 자주 접근하는 원격 데이터를 로컬 디스크에 복사하여 저장해 두면 다음 번 접근 시 네트워크를 통해 원격 시스템에서 다시 가져오는 것보다 훨씬 빠르게 데이터를 읽을 수 있다.
운영체제는 하드웨어 장치(CPU, Main Memory, I/O Devices, Bus)를 관리하고, 응용 프로그램과 하드웨어 사이에서 중재자 역할을 한다.
두 번째 목적, 하드웨어 사용을 단순화하기 위해 운영체제는 "추상화(Abstraction)" 개념을 사용한다.
프로세서, 주기억장치, 입출력 장치 등 시스템의 핵심 자원들을 추상화한 것이다. 프로세스는 실행 중인 프로그램의 인스턴스로, 운영체제는 여러 프로세스가 마치 자신만이 시스템 자원을 독점하는 것처럼 느끼게 한다. 하지만 실제로는 이러한 자원들을 효율적으로 할당하고 관리한다.
운영체제는 문맥 교환(Context Switch) 방식을 사용하여 여러 프로세스가 CPU 시간을 공유하는 것처럼 보이게 한다.
쉽게 말하자면,
gcc hello.c -o hello
./hello
./hello를 입력하면 운영체제가 hello라는 프로그램을 실행한다.운영체제는 프로세스를 통해 각 프로그램이 서로 간섭하지 않도록 완전히 독립되게 관리하고, 각 프로세스는 자기만의 메모리, 자기만의 상태를 갖고 돌아간다.
CPU 시간을 나눠준다의 의미
보통 컴퓨터에는 CPU 코어가 많아야 4개, 8개 정도인데, 동시에 실행되는 프로그램(프로세스)은 수십 개, 심지어 수백 개일 수도 있다. 그래서 운영체제는 하나의 CPU를 여러 프로세스가 돌아가며 사용하게 만들어야 한다.
예를 들어:
1. 브라우저를 켜둔다.
2. 동시에 음악 플레이어를 켠다.
3. 백그라운드에서 메신저가 메시지를 기다린다.
모두 동시에 실행 중처럼 보이지만, 사실은 운영체제가 CPU를 아주 빠르게 번갈아 줘가면서 실행시키는 것이다.
프로세스가 실제 물리 메모리를 직접 다루지 않고, 운영체제가 제공하는 논리적 메모리 공간이다. 프로세스가 마음껏 메모리를 쓰는 것처럼 보이게 해 주는 운영체제의 환상 기술이다. 실제 메모리가 부족해도, 각 프로그램은 마치 충분한 메모리를 독립적으로 쓰는 것처럼 실행된다.
입출력 장치, 특히 디스크를 추상화한 것이다. 프로그래머는 복잡한 디스크의 물리적 구조나 접근 방식 대신, 파일 시스템 인터페이스를 통해 데이터를 파일 단위로 편리하게 다룰 수 있다.
컴퓨터 시스템은 네트워크를 사용하여 다른 시스템과 통신할 수 있다. 네트워크는 서로 연결된 컴퓨터 시스템들의 집합체로 간주한다.
인터넷의 출현과 글로벌 네트워크의 확산으로 인해 컴퓨터의 활용이 크게 증가했으며, FTP, 이메일, 웹 브라우징, telnet과 같은 일반적인 네트워크 응용 프로그램들은 모두 네트워크를 통해 데이터를 복사하는 기능으 사용한다.
k 값이 무한대로 커지더라도, 즉 개선된 부분이 이론상 무한히 빨라지더라도, 전체 시스템의 최대 속도 향상은 1 / (1 - a)를 넘을 수 없다.a값이 큰 부분을 개선해야 한다는 것을 의미한다. 일부만 개선해서는 전체 성능 향상에 한계가 있다.