강좌 목록으로 돌아가기
AI031 Professional

컴퓨터 시스템: 프로그래머의 관점 (글로벌 에디션)

컴퓨터 시스템이 프로그램을 실행하고 정보를 저장하는 방식에 대한 종합적인 심층 분석입니다. 이 과정은 고수준 프로그래밍과 하드웨어 기반의 구조 사이의 간격을 메우며, 머신 레벨 표현, 프로세서 아키텍처, 메모리 계층 구조 및 동시 프로그래밍을 다룹니다.

5.0
36.0h
955 학생들
0 좋아요
인공지능
수강 시작하기

강좌 개요

📚 콘텐츠 요약

컴퓨터 시스템이 프로그램을 실행하고 정보를 저장하는 방식에 대한 종합적인 심층 분석. 이 과정은 고수준 프로그래밍과 기반 하드웨어 사이의 간극을 메우며, 머신 레벨 표현, 프로세서 아키텍처, 메모리 계층 구조, 동시 프로그래밍을 다룹니다.

하드웨어-소프트웨어 인터페이스를 이해함으로써 시스템 프로그래밍의 예술을 마스터하세요.

저자: Randal E. Bryant, David R. O'Hallaron

감사의 말: 카네기 멜론 대학교 15-213 강의의 수강생 및 강사들에 의해 지원됨. Manasa S.와 Mohit Tahiliani의 기여도 포함.

🎯 학습 목표

  1. 시스템 내에서 비트와 맥락을 사용하여 정보가 어떻게 표현되는지 식별하기.
  2. 소스 코드에서 실행 파일까지의 컴파일 시스템의 네 단계를 추적하기.
  3. 하드웨어의 조직 구조와 저장 장치의 계층적 특성을 설명하기.
  4. 십진수, 이진수, 16진수 표기법 간 변환하고 머신 레벨 주소 지정(엔디언)을 설명하기.
  5. C에서 비트 수준 및 논리 연산을 수행하고 산술 시프트의 결과를 예측하기.
  6. 정수 인코딩을 분석하여 오버플로우 취약점과 형변환 오류를 식별하기.
  7. 분석: C 문구(루프, 분기, 절차)와 x86-64 어셈블리 명령어 간의 매핑 관계를 이해하기.
  8. 해체: 런타임 스택을 분석하여 매개변수 전달, 로컬 변수 저장, 재귀 호출 관리 방식을 설명하기.
  9. 평가: 다양한 데이터 구조의 메모리 레이아웃을 분석하고 정렬 규칙을 적용하여 전체 저장 요구량 계산하기.
  10. Y86-64 프로그래머가 볼 수 있는 상태를 정의하고 명령어를 바이트 시퀀스로 인코드/디코드하기.

🔹 수업 1: 컴퓨터 시스템 탐방

개요: 본 수업은 컴퓨터 시스템이 정보를 어떻게 표현하고, 프로그램을 번역하며, 복잡한 하드웨어와 소프트웨어 상호작용을 통해 명령을 실행하는지를 종합적으로 살펴봅니다. 소스 코드에서 실행까지의 프로그램 여정, 프로세서-메모리 격차를 극복하는 메모리 계층의 핵심 역할, 운영체제가 제공하는 추상화, 그리고 시스템 성능과 병렬 처리를 규정하는 수학 법칙을 탐구합니다.

학습 결과:

  • 시스템 내에서 비트와 맥락을 사용하여 정보가 어떻게 표현되는지 식별하기.
  • 소스 코드에서 실행 파일까지의 컴파일 시스템의 네 단계를 추적하기.
  • 하드웨어의 조직 구조와 저장 장치의 계층적 특성을 설명하기.

🔹 수업 2: 정보의 표현과 조작

개요: 본 수업은 디지털 컴퓨터가 비트 수준에서 정보를 어떻게 표현하고 조작하는지를 탐구합니다. 16진수 표기법과 머신 레벨 워드 크기에서 시작해, 정수(부호 없는 및 두의 보수)와 부동소수점 숫자(IEEE 754)의 복잡한 인코딩까지 다룹니다. 학생들은 컴퓨터 산술의 수학적 특성, 특히 오버플로우의 보안 영향과 유한 정밀도 시스템에서 반올림의 미묘함을 분석하게 됩니다.

학습 결과:

  • 십진수, 이진수, 16진수 표기법 간 변환하고 머신 레벨 주소 지정(엔디언)을 설명하기.
  • C에서 비트 수준 및 논리 연산을 수행하고 산술 시프트의 결과를 예측하기.
  • 정수 인코딩을 분석하여 잠재적 오버플로우 취약점과 형변환 오류를 식별하기.

🔹 수업 3: 프로그램의 머신 레벨 표현

개요: 본 수업은 고수준의 C 프로그램이 어떻게 x86-64 머신 코드로 변환되는지에 대한 종합적인 심층 분석을 제공합니다. 프로세서의 기본 아키텍처(레지스터, 스택 포함), 제어 흐름(조건문, 루프, 스위치)의 구현, 절차 호출과 재귀의 메커니즘, 배열, 구조체, 공용체와 같은 복잡한 데이터 구조의 머신 레벨 표현 방식을 다룹니다. 마지막으로 버퍼 오버플로우 분석을 통한 시스템 보안과 부동소수점 연산에 사용되는 특수 명령어를 다룹니다.

학습 결과:

  • 분석: C 문구(루프, 분기, 절차)와 x86-64 어셈블리 명령어 간의 매핑 관계를 이해하기.
  • 해체: 런타임 스택을 분석하여 매개변수 전달, 로컬 변수 저장, 재귀 호출 관리 방식을 설명하기.
  • 평가: 다양한 데이터 구조의 메모리 레이아웃을 분석하고 정렬 규칙을 적용하여 전체 저장 요구량 계산하기.

🔹 수업 4: 프로세서 아키텍처

개요: 본 수업은 프로세서의 기본 아키텍처를 탐구하며, 순차적 구현(SEQ)에서 고성능 파이프라인 구현(PIPE)으로의 전환을 Y86-64 명령어 집합 아키텍처(ISAs)를 활용해 설명합니다. 학생들은 명령어가 어떻게 인코딩되고, 각 단계(선택, 디코딩, 실행, 메모리 접근, 기록)를 거쳐 처리되는지 분석하고, 제어 논리, 스토킹, 포워딩을 통해 하드웨어 난항을 관리하여 처리량을 극대화하는 방법을 배웁니다.

학습 결과:

  • Y86-64 프로그래머가 볼 수 있는 상태를 정의하고 명령어를 바이트 시퀀스로 인코드/디코드하기.
  • HCL(Hardware Control Language)을 사용하여 조합 회로와 순차 회로의 하드웨어 제어 논리를 구현하기.
  • 순차적 프로세서의 여섯 단계를 따라 명령어 흐름을 추적하고 클럭의 영향을 식별하기.

🔹 수업 5: 프로그램 성능 최적화

개요: 본 수업은 고수준 코드, 최적화 컴파일러, 현대 마이크로프로세서 아키텍처 간의 상호작용을 이해함으로써 프로그램 성능을 개선하는 체계적인 접근법을 탐구합니다. 메모리 앨리어싱과 같은 "최적화 차단 요소"를 식별하고, 루프 전개와 재결합과 같은 저수준 변환을 적용하며, 성능 병목을 효과적으로 타겟팅하기 위해 GPROF와 같은 프로파일링 도구를 활용하는 방법을 배웁니다.

학습 결과:

  • 메모리 앨리어싱과 절차 호출 오버헤드 등 최적화 차단 요소를 식별하고 완화하기.
  • 원소당 사이클 수(CPE) 지표를 사용하여 프로그램 성능을 정량화하기.
  • 루프 전개, 다중 누산기, 재결합 변환을 적용하여 명령 수준 병렬성 활용하기.

🔹 수업 6: 메모리 계층 구조

개요: 본 수업은 메모리 계층 구조의 구조적 및 기능적 설계를 탐구하며, 저장 속도, 비용, 용량 사이의 트레이드오프에 초점을 맞춥니다. 현재 시스템을 구동하는 기술—SRAM, DRAM, 디스크, SSD—를 자세히 설명하고, 시간적·공간적 국소성의 원칙(Principle of Locality)이 작은 고속 캐시 메모리가 프로그램 성능을 크게 향상시키는 이유를 설명합니다. 학생들은 직접 매핑, 세트 연관, 완전 연관 캐시 매핑을 분석하고, 루프 재정렬과 블로킹과 같은 최적화 기법을 사용하여 캐시 친화적인 코드 작성 방법을 배웁니다.

학습 결과:

  • SRAM, DRAM, ROM, 플래시 메모리 기술 간의 차이를 구분하고 계층 구조 내에서의 역할을 설명하기.
  • 기하학적 및 작동 구성 요소를 기반으로 디스크 저장 용량과 전체 접근 시간 계산하기.
  • 메모리 주소를 분석하여 다양한 매핑 전략에서 캐시 세트 인덱스, 태그, 블록 오프셋 결정하기.

🔹 수업 7: 링킹

개요: 본 수업은 코드와 데이터를 하나의 파일로 집계하여 메모리에 로드하고 실행할 수 있도록 하는 중요한 시스템 수준 프로세스인 링킹을 탐구합니다. 학생들은 소스 코드에서 실행 가능한 바이너리로의 전환 과정을 경험하며, 링커가 심볼 참조를 해결하고 리로케이션을 통해 섹션을 병합하고, 정적 및 동적 라이브러리를 관리하는 방식을 이해하게 됩니다. 수업은 현대 공유 라이브러리에서 사용되는 라이브러리 인터포지션과 위치 독립 코드(PIC)와 같은 고급 기법으로 마무리됩니다.

학습 결과:

  • 컴파일러 드라이버를 통해 소스 파일이 최종 실행 파일로 변환되는 과정을 추적하기.
  • ELF 객체 파일을 분석하여 심볼 유형과 섹션 조직 구조 식별하기.
  • 중복 이름과 링크 타임 의존성을 관리하기 위한 심볼 해석 규칙 적용하기.

🔹 수업 8: 예외적 제어 흐름

개요: 본 수업은 컴퓨터 시스템이 시스템 상태 변화에 반응하는 메커니즘인 예외적 제어 흐름(ECF)을 탐구합니다. 하드웨어가 트리거한 예외(예: 인터럽트, 트랩, 펄스, 중단), 운영체제 수준의 컨텍스트 스위칭프로세스 제어(fork, wait, execve), 소프트웨어 수준의 시그널비로컬 점프까지 시스템 전반에 걸쳐 구현된 방식을 살펴봅니다. 학생들은 동시성 관리, 시스템 오류 처리, 신뢰성 있는 시그널 안전 코드 작성 방법을 배웁니다.

학습 결과:

  • 하드웨어 수준 예외의 네 가지 클래스(인터럽트, 트랩, 펄스, 중단)를 구분하고 그 처리 메커니즘 설명하기.
  • 프로세스 생명주기를 fork 생성, waitpid 수확, execve 실행을 위한 시스템 호출을 사용해 관리하기.
  • 동시성, 비큐잉 시그널, 비동기 시그널 안전성 등을 고려한 안전한 시그널 핸들러 구현하기.

🔹 수업 9: 가상 메모리

개요: 본 수업은 각 프로세스가 큰, 연속적이고 개인적인 주소 공간을 제공하는 기본 추상화인 가상 메모리(Virtual Memory, VM)를 탐구합니다. 이를 통해 메모리 캐싱의 효율성, 메모리 관리 및 보호, 메모리 매핑의 기초라는 세 가지 주요 역할을 다룹니다. 또한 주소 변환(테이블 룩업 버퍼, TLB), 동적 메모리 할당(힙 관리), 자동 수집 기반의 가비지 컬렉션 원칙을 설명하고, C 프로그래밍에서 발생할 수 있는 중요한 메모리 관련 함정을 마무리로 다룹니다.

학습 결과:

  • 물리적 주소와 가상 주소를 구분하고 메모리 관리 장치(MMU)의 역할 설명하기.
  • 페이지 테이블과 번역 검색 버퍼(TLB)를 사용하여 가상 주소에서 물리적 주소로 변환하기.
  • 은유적/명시적 리스트, 융합을 포함한 동적 메모리 할당 전략 분석 및 구현하기.

🔹 수업 10: 시스템 수준 입출력

개요: 본 수업은 리눅스 운영체제와 애플리케이션 프로그램 간 입력 및 출력을 수행하는 기본 인터페이스를 탐구합니다. 유닉스 입출력 시스템 호출, 리눅스 파일 시스템에서 만나는 다양한 파일 유형, 그리고 이를 관리하기 위한 커널 수준의 데이터 구조를 다룹니다. 또한 짧은 카운트 문제를 처리하기 위한 강력한 입출력(RIO) 패키지를 소개하고, 네트워크 프로그래밍과 같은 다양한 프로그래밍 맥락에서 표준 입출력과 시스템 수준 입출력을 선택하는 가이드라인을 제공합니다.

학습 결과:

  • 유닉스 입출력 인터페이스(open, close, read, write)를 사용하여 기본 파일 작업 구현하기.
  • 일반 파일, 디렉터리, 링크를 구분하고 stat을 사용하여 파일 메타데이터 조회하기.
  • RIO 패키지를 활용하여 강력하고 버퍼링되거나 버퍼링되지 않은 입출력 작업 수행하기.

🔹 수업 11: 네트워크 프로그래밍

개요: 본 수업은 클라이언트-서버 프로그래밍 모델과 글로벌 IP 인터넷 중심의 네트워크 기반 애플리케이션의 기본 아키텍처를 탐구합니다. 학생들은 시스템 수준 네트워크 통신의 주요 API인 소켓 인터페이스를 탐색하고, 정적 파일과 동적 콘텐츠를 제공할 수 있는 기능적인 웹 서버(TINY)를 구현하는 방향으로 나아갑니다. 동적 콘텐츠는 공통 게이트웨이 인터페이스(CGIs)를 통해 제공됩니다.

학습 결과:

  • 클라이언트-서버 모델의 요청-응답 사이클과 글로벌 IP 인터넷의 하드웨어/소프트웨어 계층 구조 이해하기.
  • getaddrinfo와 같은 프로토콜 독립 함수를 사용하여 IP 주소, 도메인 이름, 소켓 구조를 조작하고 변환하기.
  • 프로세스 제어와 입출력 리디렉션을 활용하여 동적 콘텐츠를 제공하는 강력한 반복적 웹 서버와 CGI 프로그램 구현하기.

🔹 수업 12: 동시 프로그래밍

개요: 본 수업은 동시성의 기본 모델인 프로세스, 입출력 다중화, 스레드를 탐구합니다. 레이스 컨디션을 해결하기 위한 세마포어를 이용한 동기화, 생산자-소비자 및 프리스레드 서버와 같은 일반적인 아키텍처 패턴, 병렬 성능 평가에 사용되는 지표를 깊이 있게 다룹니다. 마지막으로 스레드 안전성, 재진입 가능성, 사각 지대 예방과 같은 중요한 신뢰성 문제를 다룹니다.

학습 결과:

  • 프로세스 기반, 입출력 다중화, 스레드 기반 동시성 모델의 차이를 구분하기.
  • 세마포어 연산(P 및 V)을 적용하여 상호 배제를 보장하고 동기화 패턴 해결하기.
  • 다양한 확장 법칙 아래에서 병렬 성능 지표(속도 향상, 효율성) 계산하기.