CSAPP 독서 내용 정리 1-4 ~ 1-9

이형준·2023년 4월 30일
0

CSAPP

목록 보기
2/10

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

일전의 과정으로 hello.c 소스 프로그램은 컴파일 시스템에 의해 hello라는 실행가능한 목적파일로 번역되어 디스크에 저장되었다. *쉘을 통해 이 실행파일을 유닉스 시스템에서 실행해 보자.

linux>./hello
hello, world
linux>

쉘은 커맨드라인 인터프리터로, 프롬포트를 출력하고 명령어를 입력받아 그 명령을 실행한다. 만일 명령어 라인이 내장 쉘 명령어가 아니라면 쉘은 실행파일의 이름으로 판단하고 그 파일을 로딩해서 실행해 준다. hello를 로딩하고, 실행한 뒤에 종료를 기다리는 모습.

시스템의 하드웨어 조직

  • 전형적인 시스템에서의 하드웨어 조직도

버스(Buses): 시스템 내를 관통하는 전기적 배선군. 컴포넌트들 간에 바이트 정보들을 전송한다. 일반적으로 워드(word)라고 하는 고정 크기의 바이트 단위로 데이터를 전송하도록 설계되는데, 컴퓨터에서 흔히 말하는 32비트(4바이트) 64비트(8바이트)가 바로 CPU가 다루는 워드 크기를 의미한다.

입출력 장치: 시스템과 외부세계와의 연결을 담당하는 친구들. 키보드와 마우스, 출력용 디스플레이, 데이터와 프로그램의 장기 저장을 위한 디스크 드라이브 등이 여기 속한다.

메인 메모리: 프로세서가 프로그램을 실행하는 동안 데이터와 프로그램을 모두 저장하는 임시 저장장치. 이는 물리적으로 DRAM(Dynamic Random Access Memory)칩들로 이루어져 있다.

프로세서: 주처리장치(CPU)라고 하는 이 녀석은 메인 메모리에 저장된 인스트럭션들을 해독(실행)하는 엔진이다. 프로세서의 중심에는 워드 크기의 저장장치(or 레지스터)인 프로그램 카운터(PC)가 존재한다. 프로세서는 PC가 가리키는 메모리로부터 인스트럭션을 읽어오고, 이 인스트럭션에서비트들을 해석하여 인스트럭션이 지정하는 간단한 동작을 실행하고, PC를 다음 인스트럭션 위치로 업데이트한다. 생각보다 CPU가 엄청나게 복잡한 일을 하는 줄 알았는데, 그렇지 않은게 신기하네 🤔 다만, 최신의 프로세서들은 실행 속도를 높이기 위해 훨씬 더 복잡한 방식을 사용한다고 한다.

hello 프로그램의 실행

  1. 사용자가 "/hello"를 입력하면, 쉘 프로그램은 각각의 문자를 레지스터에 읽어들인 후, 메모리에 저장한다.
  2. 사용자가 키보드에서 엔터키를 누르면 쉘은 명령 입력을 끝마쳤다는 것을 알게 되고, 쉘은 파일 내의 코드와 데이터를 복사하는 일련의 인스트럭션을 실행하여 실행파일 hello를 디스크에서 메인 메모리로 로딩한다.
  3. hello 목적파일의 코드와 데이터가 메모리에 적재된 후, 프로세서는 hello 프로그램의 main 루틴의 기계어 인스트럭션을 실행하기 시작한다.
  4. 이 인스트럭션들은 "hello world\n" 스트링을 메모리부터 레지스터 파일로 복사하고, 디스플레이 장치로 전송하여 화면에 글자들이 표시된다.

추가 공부: 레지스터와 메인 메모리 💻

레지스터와 메인 메모리는 컴퓨터의 중앙 처리 장치(CPU)에서 사용되는 두 가지 중요한 저장장치입니다. 레지스터는 CPU 내부에 위치하며, 매우 빠른 속도로 데이터를 읽고 쓸 수 있습니다. 반면에 메인 메모리는 CPU 외부에 위치하며, 비교적 느리지만 대용량의 데이터를 저장할 수 있습니다.

레지스터는 CPU의 명령어 실행을 위해 사용되며, CPU의 동작을 제어합니다. 프로세서는 레지스터에 저장된 값을 읽어와 계산하거나 다른 레지스터에 저장할 수 있습니다. 레지스터는 매우 빠르기 때문에, CPU가 작업을 수행하는 동안에는 반복적인 메모리 액세스를 피하고 레지스터에서 필요한 데이터를 빠르게 가져올 수 있습니다.

메인 메모리는 프로그램과 데이터를 저장하는데 사용됩니다. CPU는 메인 메모리에서 데이터를 읽어오고 쓸 수 있으며, 메모리의 주소를 사용하여 메모리에 접근할 수 있습니다. 하지만 메인 메모리의 액세스 속도는 레지스터보다 느리기 때문에, CPU가 작업을 수행하는 동안에는 가능한 한 레지스터에서 데이터를 읽어오려고 시도합니다.

일반적으로 프로그램이 실행될 때, 필요한 데이터와 코드는 메인 메모리에 로드됩니다. 그런 다음 CPU는 레지스터를 사용하여 메모리에서 필요한 데이터를 읽어오고 계산합니다. 데이터를 변경하거나 다른 연산을 수행한 후, 결과는 다시 메인 메모리에 저장됩니다. 따라서 레지스터와 메인 메모리는 CPU에서 데이터 처리를 위해 서로 협력하는 중요한 구성 요소입니다.

캐시가 중요하다.

위와 같은 간단한 예제로부터 얻을 수 있는 교훈은 시스템이 정보를 한 곳에서 다른 곳으로 이동시키는 일에 많은 시간을 보낸다는 것.

물리학의 법칙 때문에 더 큰 저장장치들은 보다 작은 저장장치들보다 느린 속도를 갖는다. 예로는 프로세서와 메모리 간의 동작 속도가 있고, 이러한 격차는 반도체 기술의 발전으로 점점 심화되고 있다. 이를 개선하기 위해 등장한 것이 캐시 메모리. 캐시 메모리에는 프로세서가 단기간에 필요로 할 가능성이 높은 정보를 임시 저장할 목적으로 사용된다. 이러한 캐시 메모리는 메인 메모리보다 훨씬 빠르게 액세스 할 수 있다. 이러한 캐시 메모리를 이용하는 프로그래머는 캐시를 활용하여 자신의 프로그램 성능을 10배 이상 개선할 수 있다.

저장장치는 계층구조를 이룬다.


모든 컴퓨터 시스템의 저장장치들은 위의 그림과 같은 메모리 계층구조로 구성되어 있다. 꼭대기부터 맨 밑바닥까지 이동할수록 저장장치들은 더 느리고, 더 크고, 바이트당 가격이 싸진다.

이러한 메모리 계층구조의 주요 아이디어는 한 레벨의 저장장치가 다음 하위레벨의 저장장치의 캐시 역할을 한다는 것이다. 레지스터는 L1을 위한 캐시이고, L1과 L2는 각각 L2, L3를 위한 캐시인 식으로.

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

hello 프로그램은 키보드나 디스플레이, 디스크나 메인 메모리에 직접 액세스하지 않았다. 이러한 부분은 운영체제(Operation System)이 관리하는데, 운영체제는 하드웨어와 소프트웨어 사이에 위치한 소프트웨어 계층으로 생각할 수 있다.

운영체제는 두 가지 주요 목적을 가진다. (1) 제멋대로 동작하는 응용프로그램들이 하드웨어를 잘못 사용하는 것을 막기 위해, (2) 응용프로그램이 단순하고 균일한 메커니즘을 사용하여 복잡하고 매우 다른 저수준 하드웨어 장치들을 조작할 수 있도록 하기 위해.

프로세스

프로세스는 실행 중인 프로그램에 대한 운영체제의 추상화다. 운영체제에서의 독립적인 실행 단위라고 이해하면 될듯. 프로세스는 대부분 CPU의 수보다 많고, 이 때 프로세서가 프로세스들을 바꿔주는 방식으로 한 개의 CPU가 다수의 프로세스를 동시에 실행하는 것처럼 보이게 해준다.

이를 문맥 전환(Context Switching)이라고 한다. 전에 컨텍스트에서를 공부할 때 알아봤듯이, 프로세스간의 전환이 일어날 때, 컨텍스트는 프로세스의 중단 지점을 기록해주는 역할을 한다.

이러한 프로세스간의 전환은 운영체제의 커널(Kernel)에 의해 관리된다. 커널은 운영체제 코드의 일부분으로, 메모리에 상주하는 녀석이다. 응용 프로그램이 운영체제에 의한 어떤 작업을 요청하면, 컴퓨터는 파일 읽기나 쓰기와 같은 특정 시스템 콜을 실행해서 커널에 제어를 넘겨준다. 그러면 커널은 요청된 작업을 수행하고 응용 프로그램으로 리턴한다. 여기서 유의할 점은 커널은 별도의 프로세스가 아닌 모든 프로세스를 관리하기 위해 시스템이 이용하는 코드와 자료구조의 집합이라는 것.

쓰레드

최근의 시스템에서는 프로세스가 실제로 쓰레드(Thread)라고 하는 다수의 실행 유닛으로 구성되어 있다. 프로세스는 운영제체로부터 자원을 할당받아 실행되는 작업 단위라면, 쓰레드는 프로세스 내에서 실행되는 더 작은 실행 단위라고 보면 될듯. 쓰레드는 프로세스 내에서 독립적인 실행 흐름을 가지며, 쓰레드를 사용하는 방식은 자원 공유, 빠른 응답, 경제성 면에서 큰 이점이 있기에 점점 중요성이 강조되는 프로그래밍 모델이다.

가상메모리

가상메모리는 각 프로세스들이 메인 메모리 전체를 독점적으로 사용하고 있는 것 같은 환상을 제공하는 추상화이다. 말이 좀 어려운데, 컴퓨터에서 사용하는 메모리 관리 기술 중 하나라고 한다. 프로세스들에게 각각의 비어있는 메모리 영역을 부여해주는 기술. 프로세스의 가상 메모리 접근은 결국 물리 메모리로의 접근으로 이어진다.

2023.05.10 내용 추가
CPU 가 참조하는 메모리 주소값을 가상 메모리(virtual memory) 라고 하고, 일련의 변환 과정에 의해 참조하게될 실제 메모리의 주소값을 물리 메모리(physical memory) 라고 합니다.https://modoocode.com/img/c/star2.svg
CPU 가 보는 메모리는 사실 가상 메모리 이고, 실제로는 일정한 크기의 조각들로 쪼개어져서 메모리의 각기 다른 영역에 대응되어 있다.

파일

파일은 그냥 더도말고 덜도말고 그냥 연속된 바이트들임! 끝!

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

지금까지 살펴본 시스템의 흐름 관점에서 봤을 때, 네트워크는 일종의 입출력장치로 볼 수 있다. 디스크에서 메모리로 파일을 로드해오듯, 네트워크를 통해 다른 컴퓨터로부터 받은 데이터를 읽어서 메인 메모리에 복사하니까.

중요한 주제들

  • 시스템은 응용프로그램의 실행이라는 궁극의 목적을 달성하기 위해 협력해야 하는 하드웨어와 시스템 소프트웨어가 서로 연결된 것이다.

Amdahl의 법칙

어떤 시스템의 한 부분의 성능을 개선할 때, 전체 시스템 성능에 대한 효과는 그 부분이 얼마
나 중요한가와 이 부분이 얼마나 빨라졌는가에 관계된다.
Tnew = (1 − a)Told + (aTold)/k = Told[(1 − a) + a/k]
S = Told/Tnew = 1/(1 − a) + a/k

동시성과 병렬성

동시성이란? 다수의 동시에 벌어지는 일을 갖는 시스템에 관한 일반적인 개념
병렬성이란? 동시성을 사용하여 시스템을 보다 빠르게 동작하도록 하는 것으로, 컴퓨터 시스템의 다양한 수준의 추상화에서 활용한다.

쓰레드 수준 동시성

곡예사가 여러 개의 공을 공중에 던지는 것과 같이, 한 개의 컴퓨터가 실행하는 프로세스를 빠르게 전환하는 방법을 사용하던 단일 프로세서 시스템과는 달리, 어떤 시스템이 여러 개의 프로세서를 가지고 하나의 운영체제의 커널의 제어 하에 동작하는 경우를 멀티프로세서 시스템이라고 한다. 1980년대 이래로 이는 대규모 계산에 이용되었지만, 최근에는 멀티코어 프로세스들와 *하이퍼쓰레딩(Hyperthreading)기법의 출현으로 일반적인 환경이 되었다.

인스트럭션 수준 병렬성

최근의 프로세서들은 여러 개의 인스트럭션을 한번에 실행할 수 있다. 한 클럭 사이클당 한 개 이상의 인스트럭션을 사용할 수 있는 프로세서를 슈퍼스케일러라고 한다. 대부분의 최근 프로세서들은 이를 지원한다.

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

SIMD(단일 명령어, 다중 데이터)는 컴퓨터 아키텍처에서 사용되는 명령어 집합이다. SIMD 명령어는 하나의 명령어로 여러 개의 데이터를 처리할 수 있도록 설계되어 있다.

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

추상화의 사용은 전산학에서 가장 중요한 개념이다. 가장 친숙한 예시로는 자바의 클래스가 있겠다. 이러한 추상화를 통해 프로그래머가 그 내부의 동작을 고려하지 않으면서 코드를 사용할 수 있게 해준다. 이를 확장해서 이해하면 좋겠다. 컴퓨터시스템에서의 주요 주제는, 실제 구현의 복잡성을 감추기 위해 여러 수준에서 추상화 표현을 제공하는 것이다.

요약

컴퓨터 시스템 - 하드웨어, 시스템 소프트웨어로 구성됨

컴퓨터 내의 정보 - 상황(컨텍스트)에 따라 다르게 해석되는 비트들의 그룹으로 표시됨

프로그램 - ASCII문자가 컴파일러와 링커를 거쳐 바이너리 실행 파일로 변환됨

프로세서 - 메인 메모리에 저장된 바이너리 인스트럭션을 읽고 해석함

메모리 - 시스템의 메모리들은 계층 구조를 지니며, CPU레지스터가 최상위, 이후 캐시 메모리, 메인 메모리, 디스크 저장장치들이 순서대로 위치한다. 아래계층일수록 크고, 바이트당 단가가 싸고, 느리다. 계층구조 상부의 저장장치들은 하부의 장치들을 위한 캐시 역할을 수행한다. 이러한 계층구조와 캐시를 이해한다면 효율적인 C 프로그래밍이 가능하다.

운영체제 커널 - 응용프로그램과 하드웨어 사이에서 중간자의 역할을 수행한다.

네트워크 - 컴퓨터 시스템이 서로 통신할 수 있는 방법을 제공한다. 시스템의 관점에서 보면, 이는 단지 또 하나의 입출력 장치이다.


하이퍼쓰레딩(Hyperthreading): 하이퍼쓰레딩은 인텔(Intel) 프로세서에서 사용되는 기술로, 하나의 물리적인 코어(core)에 두 개의 논리적인 프로세서 스레드(thread)를 할당하여 동시에 두 가지 작업을 처리하는 기술입니다. 하이퍼쓰레딩 기술을 사용하면 코어 수보다 더 많은 작업을 동시에 처리할 수 있습니다.

profile
저의 미약한 재능이 세상을 바꿀 수 있을 거라 믿습니다.

0개의 댓글

관련 채용 정보