레지스터, 메모리, 유저 스택, 가상 메모리, 캐시, 동시성과 경쟁 상태

jhj603·2025년 9월 12일
0

레지스터와 rax 레지스터

  • 레지스터 : CPU 내부에 있는 가장 빠르고 작은 고속 저장 공간.
    CPU는 메인 메모리(RAM)에 있는 데이터를 직접 처리하지 않고 필요한 데이터를 메인 메모리에서 레지스터로 가져와 연산을 수행한 뒤, 그 결과를 다시 메인 메모리에 저장.

  • PintOS와의 연관성
    시스템 콜을 구현할 때, 유저 프로그램은 커널에게 "어떤 서비스를 원하는지"와 "그 서비스에 필요한 데이터가 무엇인지"를 알려줘야 함.정보를 전달하는 가장 효율적인 방법이 레지스터를 사용하는 것.
    x86-64 아키텍처의 ABI 규약에 따르면
    - rax 레지스터 : 시스템 콜 번호(System Call Number)를 저장하는 용도.
    예를 들어, exit 시스템 콜을 1번으로 정했다면, 유저 프로그램은 rax 레지스터에 1을 넣고 시스템 콜을 호출해야 함.
    - rdi, rsi, rdx, r10, r8, r9 레지스터 : 시스템 콜에 필요한 인자들을 순서대로 저장하는데 사용.
    예를 들어, write(fd, buffer, size) 시스템 콜을 호출한다면, fdrdi에, buffer의 주소는 rsi에, sizerdx에 저장됨.


메모리와 유저 스택

  • 메인 메모리 : 프로그램의 코드와 데이터가 실행 중에 저장되는 넓은 작업 공간
    PintOS에서는 이 메모리 공간을 커널만 접근할 수 있는 커널 공간유저 프로그램이 사용하는 유저 공간으로 엄격하게 분리

  • 유저 스택 : 유저 공간 안에 있는 특별한 메모리 영역. 함수가 호출될 때마다 지역 변수, 복귀 주소, 그리고 함수에 전달되는 인자들이 이 스택에 저장.

  • PintOS와의 연관성

  1. 인자 전달(Argument Passing) : 사용자가 "echo hello"를 실행하면, 커널은 echo 프로그램을 메모리에 올린 후, 이 프로그램의 유저 스택에 문자열 "echo""hello"를 직접 써넣어줘야 함. 이 작업을 통해 echo 프로그램의 main 함수는 자신의 인자들을 스택에서 찾아 사용할 수 있게 됨.
  2. 유효성 검사 : 시스템 콜을 통해 유저 프로그램이 0x12345678이라는 주소(포인터)를 커널에 전달했을 때, 커널은 이 주소가 유효한 유저 공간에 속하는지, 그리고 실제로 할당된 페이지인지 반드시 검사해야 함. 이 검사 없이 주소에 접근했다가는 커널이 보호해야 할 다른 메모리 영역을 침범해 시스템 전체가 멈출 수 있음.

가상 메모리

  • 가상 메모리 : OS는 각 프로세스에게 실제 물리 메모리(RAM)와는 독립적인 자신만의 가상 주소 공간(Virtual Address Space)을 제공.
    이를 통해, 프로세스는 메모리 전체를 독차지하는 것처럼 느낌. 모든 프로세스는 0번지부터 시작하는 자신만의 주소 공간을 가지며, 이 가상 주소는 CPU의 메모리 관리 장치(MMU)를 통해 실제 물리 주소로 변환.

  • 가상 메모리 사용 목적
    1. 프로세스 격리 : 한 프로세스가 다른 프로세스의 메모리를 절대 침범할 수 없어 시스템이 매우 안정적으로 보호됨.
    2. 효율적인 메모리 관리 : 프로그램의 일부만 실제 메모리에 올려놓고 실행하는 것(요구 페이징)이 가능해져, 실제 RAM보다 더 큰 프로그램도 실행할 수 있음.

  • PintOS와의 연관성
    exec 시스템 콜 구현 시, 이 가상 주소 공간에 프로그램의 코드를 적재하는 과정을 흉내 내게 됨. Virtual Memory에서 이 개념을 본격적으로 다루게 됨.


캐시

  • 캐시 : CPU와 메인 메모리(RAM) 사이에 위치하는, 레지스터보다는 느리지만 메인 메모리보다는 훨씬 빠른 소규모 메모리. CPU는 자주 사용될 것으로 예상되는 데이터를 메인 메모리에서 미리 캐시에 복사. 그 후 CPU가 데이터를 필요로 할 때, 느린 메인 메모리까지 갈 필요 없이 빠른 캐시에서 데이터를 바로 가져와 시스템 전체의 성능을 크게 향상시킴.

  • PintOS와의 연관성
    캐시를 직접 제어하거나 관리할 필요가 없음. 대부분 하드웨어가 자동으로 처리하기 때문.
    다만, 내가 작성한 코드가 하드웨어에서 어떻게 더 빠르게 동작할 수 있는지 원리를 이해하는 것은 중요.
    예를 들어, 반복문에서 동일한 메모리 영역에 계속 접근하는 코드는 캐시의 효율을 극대화(캐시 히트율 증가)해 더 좋은 성능을 낼 수 있음.
    File System에서는 버퍼 캐시(Buffer Cache)라는 소프트웨어적 캐시를 직접 구현하는데, 이 하드웨어 캐시의 원리가 큰 도움이 될 것.


동시성(Concurrency)과 경쟁 상태(Race Condition)

  • 동시성 : 여러 작업이 동시에 실행되는 것처럼 보이게 하는 것. 실제로는 하나의 CPU 코어가 여러 작업을 매우 빠르게 번갈아 가며 실행(Context Switching)하는 것.

  • 경쟁 상태 : 여러 프로세스나 스레드가 공유된 자원(예 : 전역 변수, 파일)에 동시에 접근하려 할 때 실행 순서에 따라 결과가 달라지는 예측 불가능한 오류가 나타나는데 이것이 발생할 수 있는 상태를 경쟁 상태라고 함.

OS 커널은 수많은 인터럽트와 프로세스들이 동시에 공유 데이터에 접근하는 환경이므로, 경쟁 상태를 방지하는 것이 안정성의 핵심. intr_disable() 같은 동기화 기법(예 : 뮤텍스, 세마포어)을 사용해 한 번에 하나의 실행 흐름만 공유 데이터에 접근하도록 보장해야 함.

  • PintOS와의 연관성
    PintOS Project 2에서 시스템 콜 테이블 같은 공유 자원에 접근할 때 이 문제가 발생할 수 있음. Project1에서 집중적으로 학습하고 해결하게 됨.
profile
자라나라 실력 실력

0개의 댓글