Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

Question 1:

운영체제는 demand paging 시 주소 변환을 빠르게 하기 위해 하드웨어의 지원을 받는다. 이 상황에서


아래의 질문에 답하시오.
+) 하드웨어의 지원이란?
- PTE(Page table entry) : each record that makes up the page table(an entry for each page)이다.
PFN(Page frame number)와 flag bits로 구성된다.
- TLB(Translation Look-aside Buffers) : MMU 안에 위치하는 cache이다. 최근 사용된 page-frame 매
핑을 저장함으로써 주소 변환 속도를 향상 시킬 수 있으며, 페이지 테이블 및 메모리 접근의 횟수를 줄
일 수 있다.

(a) (10 pts) 프로세스 간 context switching 시 위의 상황을 적절하게 지원해주기 위해 운영체제는 어떤
동작을 해야하는지 설명하시오.

위의 상황에서 context switching으로 새로운 프로세스가 page table에 접근했을 때, 내가 reference하

고자 하는 page가 physical memory 상에 load되어야하는 상황, 즉 page fault가 발생할 수 있다. 이

경우에 운영체제는 page fault handler를 통해 이를 해결해야하는데, 다음과 같이 동작한다. 1) process

가 저장된 backing store에서 page를 찾고, 2) physical memory 상의 새로운 free frame을 찾아 이를

할당한다. 3) 새로운 free frame이 없는 경우 page replacement algorithm을 이용한다. 4) physical

memory에 page를 load한 후, 5) page table을 update하고, 6)process를 재개한다. 이외에도 실행중이던

프로세스의 상태를 저장하는 동작도 수행한다.

(b) (10pts) (a)에서 답한 운영체제 동작에서 어떤 부하가 있는지 설명하고, 이를 어떻게 개선할 수 있을

지 제안하시오.

- (a)에서 page replacement가 자주 발생하는 경우, IO operation overhead로 인해 performance

degradation이 발생할 수 있다. 또한 page fault가 발생하는 경우, CPU는 실행 중인 프로세스를 중단하

고 page fault handler를 실행하며, page table을 update해야 하므로 page fault가 자주 일어나는 경우

에 CPU overhead가 커질 수 있다.

또한, page replacement가 매우 빈번하게 발생하면 CPU가 거의 대부분의 시간을 page in, page out에

사용하는 상황인 thrashing이 발생할 수 있다. 이 경우 CPU utilization이 매우 떨어진다.

- 이를 개선하기 위해서는 최적화된 page replacement algorithm을 사용해야한다. FIFO, LFU, LRU 등

다양한 페이지 교체 알고리즘을 조정해서 사용하며 상황에 맞는 최적 알고리즘을 찾는다. 물리 메모리

용량을 늘려서 더 많은 페이지를 메모리에 상주시킴으로써 페이지 교체 빈도를 줄이는 방법도 있다.
Question 2:

[30 pts] 운영체제 커널의 코드를 학습 데이터(데이터셋)로 삼아 새로운 커널을 자동으로 구현할 수 있는 생성형 딥러

닝 모델—OSgpt를 학습(train)시키고자 한다. 이 모델을 학습시키는 프로그램들을 설계해보자. 구체적인 기능은 다음

과 같다.

• TRAIN 프로그램은 먼저 쓰레드를 순차 생성한다. 각 쓰레드는 생성 시 OSgptTrain 함수를 실행한다. 이 함수는 모

델 학습을 수행하는데, 각자 data라는 버퍼에서 자신이 사용할 데이터셋을 하나 꺼낸 다음 학습을 진행한다.

• LOAD 프로그램도 여러 쓰레드를 생성한다. 각 쓰레드는 생성 시 OSgptLoad 함수를 실행하는 데, data 버퍼에 비

어있는 슬롯이 하나 있으면 모델 학습에 사용될 커널 코드를 크롤링하여 해당 슬롯에 추가한다.

• TRAIN과 LOAD는 공유 메모리를 통해 data 버퍼를 공유한다.]=

(a) (15 pts) TRAIN과 LOAD 두 프로그램을 작성하시오.

TRAIN은 실행되면 총 10개의 쓰레드를 순차적으로 생성한다. 쓰레드 생성 시 사전에 정의된 OSgptTrain 함수를 실

행한다. TRAIN은 10개의 쓰레드가 동작을 완료할 때까지 기다린다. 이 과정을 무한 반복한다.

LOAD는 동일한 과정으로 동작하되, 각 쓰레드가 OSgptTrain 대신 OSgptLoad를 실행한다.

• OSgptTrain, OSgptLoad: 별도 구현하지 않고 호출/사용만 함. 함수 호출 시 전달되는 인자는 없음.

• 코드 구현에 필요한 헤더 파일은 모두 포함되어 있다고 가정함. 이외 코드 작성에 필요한 부분은 자유롭게 가정하고,

문제에서 요구한 부분 외에는 필수적으로 고려하지 않아도 무방함.

(b) (15pts) 이제 두 함수 OSgptTrain, OSgptLoad를 구현하고자 한다. 두 함수의 동작이 데이터셋의 관점에서

consistent하도록 작성하시오. 또한 이를 달성하는 데 필요한 primitive들과 그 초기화를 포함하시오.

• data는 다음과 같이 미리 정의됨 (MAX: 배열 크기, Dataset: 사전에 정의한 데이터셋 struct).

int MAX;

Dataset data [MAX] ;

• OSgptTrain이 읽어올 버퍼의 index로 out, OSgptLoad가 추가할 버퍼의 index로 in을 사용하시오.

• 코드 구현에 필요한 헤더 파일은 모두 포함되어 있다고 가정함. 문제에서 제시한 변수 및 동작 외에는 자유롭게 가

정하고, 문제에서 요구한 부분 외에는 필수적으로 고려하지 않아도 무방함.


Question 3:
[35 pts] TLB 기반의 demand paging (4 KB page)을 사용하는 시스템을 확장하여, 네트워크를 통해 연결
된 원격의 서버가 지닌 저장소까지 swap space로 활용할 수 있게 한다. 이 시스템은 로컬 컴퓨터의
swap space가 부족해지면, 원격 서버의 swap space를 통해 demand paging을 수행한다. 이 때, 아래의
질문에 답하시오.
(a) (10 pts) 프로세스가 자신의 특정 주소를 참조하려고 한다. 이 때, page replacement가 수행되고
(page out), 원격 서버의 swap space를 이용한다. 원격서버에 네트워크 IO를 하는 데에는 인터럽트와
programmed IO (IO instructions)를 사용한다. 프로세스의 주소 참조부터 page out이 완료되는 과정까
지를 순서대로 설명하시오.
• 네트워크 전송 과정에서 패킷 손실 등은 일어나지 않는다.
• 문제 풀이에 필요한 가정은 자유롭게 하시오.

- 가정

페이지 크기: 4 KB

TLB (Translation Lookaside Buffer) : MMU 내의 캐시

Page Table: 프로세스의 가상 주소와 물리 주소를 매핑

Local Swap Space/Remote Swap Space

Network I/O: 네트워크 인터페이스를 통해 원격 서버와 통신

인터럽트 및 Programmed I/O: 네트워크 전송을 처리


1. 프로세스의 주소 참조 : 먼저, TLB에서 해당 가상 주소에 대한 물리 주소를 찾고, 존재하지 않는 경우

페이지 테이블에서 매핑을 확인한다.

2. page fault 발생 : 페이지 테이블을 확인했을 때, 해당 페이지가 메모리에 없는 경우 page fault가 발

생하고, page fault handler가 호출된다.

3. page replacement : 새로운 free frame이 존재하지 않는 경우, page replacement algorithm을 사용

하여 교체할 victim page를 선택한다.

4. page-out 시도 : 3에서 선택된 victim page(paged-out pages)를 로컬 swap space에 저장하기 위해

시도하고, 로컬 swap space가 부족한 경우, 원격 swap space를 사용해야한다.

5. 네트워크 IO : victim page를 원격 서버에 전송하기 위해 네트워크 인터페이스를 준비하고, page data

를 패킷으로 분할한다.

6. Programmed IO : CPU는 programmed IO를 사용하여 네트워크 인터페이스에 page data를 전송하고

, 데이터는 패킷으로 분할되어 네트워크를 통해 원격 서버로 전송된다.

7. 원격 서버 : 원격 서버는 수신한 패킷을 합쳐서 swap space에 page를 저장하고, 이러한 결과 응답을

local 컴퓨터로 전송한다.

8. 원격 서버로부터 페이지가 성공적으로 저장되었다는 결과 응답이 도착하면, 네트워크 인터페이스는 인

interrupt를 발생시키며, interrupt handler는 page out 작업이 완료되었음을 알린다.

9. page table update : page out이 완료되면 page fault handler는 원격 서버의 swap space 위치를

page table에 기록하고, page table entry를 update한다.

10. page in : 참조하려던 페이지를 메모리에 load하고, 로컬 swap space 또는 원격 swap space에서

page를 load한다. 네트워크 I/O를 사용하여 원격 서버에서 페이지를 가져오는 경우, 이전의

Programmed IO와 interrupt를 사용한다.

11. 프로세스 재개 : page fault handler가 완료되었음을 알리고, 프로세스가 중단된 지점에서 재개되며

참조하려던 주소에 접근할 수 있다.


(b) (15 pts) 한 컴퓨터 내의 메모리와 IO 장치 간 1KB 데이터 복사에 시간 T가 소모된다. 또한, 한 컴퓨
터에서 다른 (원격) 컴퓨터 간 1 KB의 데이터 전송에 N의 시간이 소모된다. 이 때, (a) 과정에서 소모되는
시간을 계산하시오.
• 데이터 복사, 네트워크 전송 등 (a) 과정의 동작은 서로 중첩 및 파이프라인하여 병렬 실행할 수 없다
고 가정한다.
즉, 한 단계의 동작이 모두 완료되어야 다음 단계의 동작을 수행한다.
• 문제 풀이에 필요한 가정은 자유롭게 하시오.

(a)의 과정에서

5. 네트워크 IO 준비:

victim 페이지를 원격 서버로 전송하기 위해 네트워크 인터페이스 준비하고 페이지 데이터를 패킷으로

분할 (데이터 복사)한다.

4KB 데이터를 네트워크 인터페이스로 복사하는 데 걸리는 시간은 4×푇 = 4×T.

6. Programmed IO:

CPU가 Programmed IO를 사용하여 네트워크 인터페이스에 페이지 데이터 전송한다. 데이터는 패킷으로

분할되어 원격 서버로 전송된다.

4KB 데이터를 전송하는 데 걸리는 시간은 4×푁 =4×N

총 시간은 4T+4N이다.

(c) (10 pts) (a)의 과정에 폴링을 적용한다고 할 때, 어떠한 장단점이 있는지 설명하시오. 또한, 이 시스템
에 CPU는 충분하고, 메모리는 불충분하다고 할 때 인터럽트 기반의 처리와 폴링 기반의 처리 중 어떠한
방식이 적합한지 결정하고 그 이유를 설명하시오.

(a) 과정에서 폴링을 적용하게 되면 인터럽트 기반 처리보다 구현이 간단하여 시스템 복잡도를 줄일 수
있고, 주기적으로 device’s status register를 확인하기 때문에 예측 가능한 응답 시간을 가진다는 장점이
있습니다. 반면, 폴링은 CPU가 계속적으로 장치 상태를 확인하는데 소비되므로, 다른 작업을 수행하지
못하게 하여 비효율적이라는 단점이 있습니다.

위와 같이 CPU가 충분하고, 메모리가 불충분한 경우에는 메모리 자원의 효율적인 사용이 중요합니다. 또
한, 이 시스템에서는 page replacement, swap space management가 빈번하게 발생할 가능성이 높으르
모 인터럽트 기반 처리가 더 적합합니다. 왜냐하면, 인터럽트 기반 처리는 필요한 시점에만 CPU를 사용
하므로, CPU 자원을 효율적으로 사용할 수 있으며 CPU가 충분한 상황에서는 더욱 유리합니다. 또한, 메
모리가 불충분한 경우, page fault와 swap 작업이 빈번하게 발생하므로, 빠른 응답이 필요합니다. 인터럽
트 기반 처리는 폴링 기반 처리보다 일반적으로 빠른 응답을 제공합니다.

하지만, 폴링 주기가 인터럽트 기반 처리의 컨텍스트 스위칭 및 스케줄링에 걸리는 시간보다 짧다면, 폴
링 기반 처리 방식이 더 적합할 수 있습니다.
Question 4:
[15 pts] 프로세스에게 64-bit 크기의 가상 주소를 제공하는 운영체제를 설계한다. 주소 공간을 총 2^12
개의 페이지로 나누려할 때, 다음 질문에 답하시오.
(a) (5 pts) VPN과 offset 비트 수를 결정하시오.

1. 전체 가상 주소 공간 크기: 가상 주소 공간의 크기는 64비트이므로 2^64개의 주소 공간

2. 페이지 수: 주어진 페이지 수는 2^12개

3. 페이지 크기: 전체 가상 주소 공간 크기를 페이지 수로 나누면, 각 페이지의 크기를 구할 수 있습니다.


각 페이지의 크기 = 2^52바이트

4. Offset 비트 수: 각 페이지의 크기는 2^52바이트이므로, offset을 나타내기 위해서는 52비트가 필요

5. VPN 비트 수: 가상 주소 공간은 64비트이고, 그 중 52비트를 offset으로 사용, 따라서, VPN (Virtual


Page Number)를 나타내기 위해 필요한 비트 수는 64−52=12 비트

VPN : 12
offset : 52

(b) (5 pts) Single-level 페이지 테이블을 구성하고자 한다. 이 페이지 테이블은 모든 페이지에 대한 엔트
리를 가지고 있으며, 엔트리 당 크기는 4KB이다. 이 때, 페이지 테이블의 크기를 계산하시오.

총 페이지 수가 2^12 페이지이므로, 2^12개의 엔트리가 필요


2^12 * 4KB(2^12바이트) = 2^24바이트=16MB

(c) (5 pts) 프로세스가 100개 실행될 때, (b)에서 설계한 page table이 소모하는 전체 메모리 크기를 계산
하시오.

프로세스마다 page table을 가지므로, 100 x 16MB = 1600MB


Question 1:
[40 pts] As a system engineer, you are choosing how to manage the memory of your computer
system. Answer the following questions.
(a) (8 pts) With contiguous allocation and MMU : Describe what things the kernel should do when
context switching from one process to another to maintain contiguous allocation.

Contiguous allocation(연속 할당)은 address space를 physical memory에 연속적으로 할당하는 것으

로 context switch가 발생하는 경우 커널은 1) 현재 process의 base register, bound register values

를 PCB에 저장하고 이후에 restore합니다. 2) 다음 process의 경우 어느 free space에 address space

를 위치시킬 것인지 결정해야하는데, contiguous allocation strategies(first-fit, best fit, worst-fit 등)

을 이용하여 start address(base)를 결정하고, MMU를 update합니다.

(b) (8 pts) With segmentation and MMU : Describe what things the kernel should do when context
switching from one process to another to maintain segmentation.

Segmentation을 사용하는 경우, 전체 address space를 연속 할당하는 대신, address space의 각각의
logical segment를 연속 할당하는 방법입니다. Contiguous allocation과 유사하게 1) 현재 프로세스의
각각의 segment의 base register와 bound register를 PCB에 저장하고 저장하고, 이후에 restore합니다.
2) 다음 process의 경우 각 segment에 대해 contiguous allocation strategies을 이용하여 base
register와 bound reigster를 설정합니다. 이를 통해 해당 segment의 start address와 크기를 정의하고,
MMU를 update합니다.

(c) (8 pts) With paging and TLB: Describe what things the kernel should do when context switching
from one process to another to maintain paging.

Paging의 경우 address space와 physical memory가 fixed-size로 나누어지고, address spaces가


physical memory로 distributed됩니다. 이러한 paging과 TLB를 사용하는 상황에서 context switching
이 발생하는 경우 1) 현재 process의 page table 정보를 저장합니다. 이전에 변환되었던 virtual
address에 대한 subsequent acess의 경우는 page table을 거치지 않고 TLB에 저장된 정보를 이용합니
다. 하지만 그렇지 않은 경우에 kernel은 새로운 process의 page table 정보를 load함으로써 paging을
maintain할 수 있습니다.
(d) (10 pts) Based on your answers from (a)–(c), list in order which of contiguous allocation,
segmentation, and paging make context switching complex and explain why.

연속 할당 > 세그멘테이션 > paging

1. 연속 할당:

- 복잡성: 연속 할당은 프로세스의 주소 공간을 연속적인 메모리 블록에 할당하는 방식입니다. 따라서 프
로세스의 크기가 메모리에 연속적으로 맞아야 하며, 이를 위해 메모리 내의 연속적인 빈 공간을 찾는 것
이 필요합니다.

- 변경 시 필요한 작업: 컨텍스트 스위칭 시, 현재 실행 중인 프로세스의 메모리 블록 정보(베이스, 바운


드 레지스터 등)를 저장하고, 다음 프로세스를 위한 적절한 연속적인 메모리 블록을 찾아야 합니다. 이
과정에서 메모리 단편화 문제와 최적화 전략(최적적인 메모리 할당 위치 찾기)이 발생할 수 있어 복잡도
가 높습니다.

2. 세그멘테이션:

- 복잡성: 세그멘테이션은 프로세스의 주소 공간을 논리적인 세그먼트 단위로 분할하여 관리하는 방식입
니다. 각 세그먼트는 다른 크기를 가질 수 있으며, 따라서 각 세그먼트를 메모리에 할당할 때 크기와 위
치를 맞춰야 합니다.

- 변경 시 필요한 작업: 컨텍스트 스위칭 시, 현재 실행 중인 프로세스의 각 세그먼트의 베이스와 바운드


레지스터를 저장하고, 다음 프로세스의 각 세그먼트에 대해 새로운 메모리 위치를 결정해야 합니다. 하지
만, 세그멘테이션의 경우 각 세그먼트가 독립적으로 관리되기 때문에 적절한 메모리 공간을 찾는 과정이
상대적으로 단순하며 메모리 단편화 문제를 연속 할당보다 더 효과적으로 다룰 수 있습니다.

3. 페이징:

- 복잡성: 페이징은 고정된 크기의 페이지로 나누어진 주소 공간을 관리합니다. 각 페이지는 일정한 크기
를 가지며, 페이지 테이블을 통해 가상 주소를 물리 주소로 변환합니다.

- 변경 시 필요한 작업: 컨텍스트 스위칭 시, 현재 프로세스의 페이지 테이블을 저장하고, 다음 프로세스


의 페이지 테이블을 로드합니다. 페이지 테이블의 업데이트는 상대적으로 간단하며, TLB를 통해 빠르게
접근할 수 있어서 주소 변환 비용이 낮습니다. 페이지의 고정된 크기와 페이지 단위 할당으로 인해 메모
리 할당이나 해제 시의 복잡성이 크게 줄어듭니다.
(e)–(g) True or False: Mark ⃝ for True, × for False. Provide a simple reason for your choice.
Currently, our computer system (single-core CPU) is running two processes—process A and
process B. Now, process A occupies the CPU. Then, context switching occurs, and process B
occupies the CPU. Let’s compare the time in converting a virtual address to a physical address
(address translation speed) before and after the context switch.
* Note that the pages the processes attempt to reference (read or write) are already loaded in
main memory (no page faults).

(e) (2 pts) With contiguous allocation and MMU: after context switching, the address translation
speed of process B can be slower than A.
O, 연속할당의 경우 context switching이 발생하면, process B에 대해 어느 free space에 address
space를 위치시킬지 결정하고, MMU를 update해야한다. 이 과정에서 free space를 탐색하고, start
addess를 결정하는데 추가적인 시간이 필요할 수 있어 주소 변환 속도가 A보다 느릴 수 있다.

(f) (2 pts) With segmentation and MMU: after context switching, the address translation speed of
process B can be slower than A.
O, 세그멘테이션도 마찬가지로, 어느 free space에 각각의 segmentation을 위치시킬지 결정해야하므로
A보다 느릴 수 있다.

(g) (2 pts) With paging and TLB: after context switching, the address translation speed of process B
can be slower than A.
X, 각각의 process는 각각의 page table을 가지며 주소 변환 과정은 각각의 page table에서 page가 할
당된 frame을 찾는 과정이다. 또한, TLB는 자주 사용되는 PTE를 캐시하여 주소 변환 속도를 빠르게 하
므로, 프로세스 B의 주소 변환 속도가 프로세스 A보다 느릴 수 없다.
Question 2:
[30 pts] You are now designing synchronization mechanisms for your kernel.
(a) (10 pts) You implemented a spin lock primitive using atomic instructions and observed that the
spin lock works properly in your system. As a result, no further implementations of locks, such as
spin lock with yield or yield with queue, are necessary (Yeah!). Guess and provide reasons why the
spin lock can be effective on your system.

1. 적은 경쟁: 시스템에서 락을 요청하는 스레드가 많지 않다면, 즉 락에 대한 경쟁이 낮다면 스핀락이


효과적일 수 있습니다. 이 경우 스레드들이 락을 기다리는 시간이 짧기 때문에 바쁜 대기(busy-waiting)
로 인한 비용이 적습니다.

2. 짧은 (Critical Section): 스핀락으로 보호되는 critical section의 코드가 매우 짧다면, 스레드가 락을


점유하는 시간이 최소화됩니다. 이는 다른 스레드들이 기다리는 시간을 줄여주어 스핀락의 오버헤드가
무시할 만한 수준이 됩니다.

3. 높은 프로세서 availability: 프로세서가 자주 idle 상태이거나 스핀 대기 중인 스레드를 처리할 수 있


는 충분한 프로세서가 있는 시스템에서는 스핀락이 효과적일 수 있습니다. This is because the cost of
busy-waiting is offset by the availability of CPU cycles that would otherwise be unused.

4. Real-Time Requirements : 스핀락은 스레드가 대기 상태로 들어갈 여유가 없고 가능한 빨리 락을 획


득해야 하는 실시간 시스템에 적합합니다. context switch의 오버헤드 없이 빠르게 락을 획득하고 해제할
수 있기 때문에 이러한 상황에서 스핀락이 유리할 수 있습니다.

5. *단순성과 낮은 오버헤드: 스핀락은 구현이 간단하며 context switch, 대기 큐 관리, 커널 개입 등의


오버헤드가 없습니다. 이러한 단순성은 특정 상황에서 성능 이점을 제공할 수 있습니다.

6. Processor Architecture and Cache Coherence : 현대 프로세서는 atomic operations과 cache


coherence protocols을 효율적으로 지원하므로 스핀락이 효율적일 수 있습니다. 예를 들어, Test-and-
Set 또는 Compare-and-Swap과 같은 atomic instructions를 사용하면 락 연산이 하드웨어에 의해 효
율적으로 처리됩니다.

7. 예측 가능한 타이밍: 스핀락은 context switching을 수반하는 다른 락 메커니즘에 비해 더 예측 가능


한 타이밍을 제공합니다. 이러한 예측 가능성은 타이밍과 동기화에 대한 엄격한 제어가 필요한 특정 애
플리케이션에서 중요할 수 있습니다.

8. 선점(Preemption) 없음: 시스템이 선점형 멀티태스킹이 아닌 환경(예: 단일 스레드 또는 협동 멀티태


스킹 시스템)에서 실행되는 경우, 스핀락의 비효율성과 관련된 문제는 최소화됩니다. 이는 락을 점유한
스레드가 중단 없이 완료될 가능성이 높기 때문입니다.
(b) (10 pts) Based on the spin lock, I implemented multi-threaded processes as follows. First, here
is a function for
handling bank transactions.
function transfer_funds(account_from , accoun_to , amount ) {
lock(account_from) ;
lock(account_to) ;
if (account_from.balance >= amount ) {
account_from.balance −= amount ;
account_to.balance += amount ;
}
unlock(account_to) ;
unlock(account_from) ;
}
I created two threads. Thread 1 executes the following instruction:
transfer_funds(AccountX , AccountY , 500 ) ;

Thread 2 executes the following instruction:

transfer_funds( AccountY , AccountX , 300 ) ;

Sadly, it seems that the above implementations have a ”problem.” Describe the types of potential
problems that could happen and why (e.g., how) they happen

Potential Problems:

1. Deadlock:
- Consider two threads, Thread 1 and Thread 2.
1) Thread 1 starts executing transfer_funds(AccountX, AccountY, 500).
=> It locks AccountX.
=> It attempts to lock AccountY but gets preempted by the scheduler.
2) Thread 2 starts executing transfer_funds(AccountY, AccountX, 300).
=> It locks AccountY.
=> It attempts to lock AccountX but is blocked because AccountX is already locked by Thread 1.
3) Now, Thread 1 is waiting to lock AccountY (which is held by Thread 2), and Thread 2 is waiting
to lock AccountX (which is held by Thread 1). This creates a circular wait condition, resulting in a
deadlock. Both threads are stuck waiting for each other to release the lock, and neither can
proceed.

2. Priority Inversion:
- Suppose there are three threads with different priorities: high, medium, and low.
1) The low-priority thread locks AccountX and gets preempted by the medium-priority thread,
which does some unrelated work.
2) Meanwhile, the high-priority thread attempts to lock AccountX but is blocked by the low-
priority thread.
3) Since the medium-priority thread is running, it prevents the low-priority thread from running
and releasing the lock. The high-priority thread is effectively blocked by a lower-priority thread,
causing priority inversion.

3. Inefficiency with Busy-Waiting:


- Spin locks involve busy-waiting, where a thread continuously checks for the lock to become
available.
This can be very inefficient, especially if the critical section is long or the system is under heavy
load, leading to wasted CPU cycles.
For example, if AccountY is locked by Thread 2 and Thread 1 is continuously spinning to acquire
the lock, it wastes CPU resources that could be used for other productive work.

(c) (10 pts) Please provide a pseudo-code implementation that addresses the potential problems
mentioned in question (b).

# 계정 객체 정의

class Account:

def __init__(self, balance):

self.balance = balance

self.lock = Mutex() # 뮤텍스를 사용하여 락 구현

# 계정을 항상 일관된 순서로 잠그는 함수

def lock_accounts(account1, account2):

if account1 < account2:

account1.lock.acquire()

account2.lock.acquire()

else:

account2.lock.acquire()

account1.lock.acquire()

# 계정 잠금을 해제하는 함수

def unlock_accounts(account1, account2):

account1.lock.release()

account2.lock.release()
# 우선순위 상속 메커니즘 적용 함수

def inherit_priority(current_thread, waiting_thread):

if waiting_thread.priority > current_thread.priority:

current_thread.priority = waiting_thread.priority

# 자금 이체 함수

def transfer_funds(account_from, account_to, amount):

# 우선순위 상속 적용 (선택 사항)

current_thread = get_current_thread()

waiting_thread = get_waiting_thread(account_from, account_to)

inherit_priority(current_thread, waiting_thread)

# 계정 잠금

lock_accounts(account_from, account_to)

# 잔액 확인 및 자금 이체

if account_from.balance >= amount:

account_from.balance -= amount

account_to.balance += amount

# 계정 잠금 해제

unlock_accounts(account_from, account_to)

# 우선순위 복원 (선택 사항)

restore_priority(current_thread)

# 스레드 생성 및 실행 예제

thread1 = Thread(target=transfer_funds, args=(AccountX, AccountY, 500))

thread2 = Thread(target=transfer_funds, args=(AccountY, AccountX, 300))

thread1.start()

thread2.start()

thread1.join()

thread2.join()
Question 3:
[30 pts] Finally, you are designing demand paging system for our OS. This demand paging system
uses a hard disk as
backing storage.
The address space has 16 pages. The size of virtual address is 6 bit. A process runs and accesses
the following virtual
addresses in sequence:
• T0: 000100 (4 in decimal) : 페이지 번호 1
• T1: 001010 (10 in decimal) : 2
• T2: 000100 (4 in decimal) : 1
• T3: 001011 (11 in decimal) : 2
• T4: 001010 (10 in decimal) : 2
• T5: 001011 (11 in decimal) :2
• T6: 000100 (4 in decimal) : 1
• T7: 001010 (10 in decimal) : 2
• T8: 001011 (11 in decimal) : 2
• T9: 000100 (4 in decimal) :1

(a) (4 pts) Calculate the virtual page numbers and offset values each for 000100 (4 in decimal),
001010 (10 in decimal), and 001011 (11 in decimal).

6비트의 가상 주소에서 페이지 번호가 4비트를 차지하고, 오프셋이 2비트를 차지하게됨.


1) 000100
페이지 번호 : 상위 4비트, 0001(1 in decimal)
오프셋 : 하위 2비트, 00(0 in decimal)

2) 001010
페이지 번호 : 상위 4비트, 0010(2 in decimal)
오프셋 : 하위 2비트,10(2 in decimal)

3) 001011
페이지 번호 : 상위 4비트, 0010(2 in decimal)
오프셋 : 하위 2비트, 11(3 in decimal)

(b) (6 pts) You want to apply working set algorithm in my system with the window size (∆) as four.
Provide WS(T2), WS(T4), WS(T5), WS(T7), WS(T8) and WS(T9).

1) WS(T2) : {1, 2}
2) WS(T4) : {1, 2}
... 모두 동일
(c) (10 pts) Assume that you know the memory accesses of this process (from T0 to T9) in advance.
Based on this knowledge, determine the appropriate number of frames to maintain in memory for
this process.

모든 시간에서 접근하는 페이지 번호들을 확인해보면 고유한 페이지 번호는 : 페이지 번호: 1, 2
따라서, 이 프로세스가 참조하는 고유한 페이지는 총 두 개입니다. 이를 기반으로 적절한 프레임 수를 결
정하려면 최소한 이 두 페이지가 메모리에 항상 유지되도록 해야 합니다.

=> 프로세스가 page fault 없이 효율적으로 실행되기 위해 유지해야 할 프레임 수는 고유한 페이지 수
와 같습니다. 따라서 적절한 프레임 수: 2
이 프로세스는 최소한 2개의 프레임을 메모리에 유지해야 합니다.

(d) (10 pts) Our system runs many more processes concurrently. So it experiences frequent page
outs and swapping. You are considering whether to use 1) polling or 2) DMA for the page out and
swapping between memory and the hard disk. Choose one of the two options and provide your
reasons on the choice.

- DMA
1. CPU 활용도 향상:
- DMA는 데이터를 메모리와 디스크 사이에 전송하는 작업을 전담하는 컨트롤러를 사용합니다. CPU가
데이터 복사를 직접 수행하지 않고, 대신 DMA 컨트롤러에 작업을 맡기면 CPU는 다른 작업을 수행할 수
있습니다. 이는 시스템의 전반적인 성능을 향상시키는 데 도움이 됩니다.

2. 효율적인 데이터 전송:


- DMA는 대량의 데이터를 효율적으로 전송할 수 있도록 설계되었습니다. 페이지 아웃 및 스와핑은
많은 데이터를 전송해야 하는 작업이므로, DMA의 사용이 적합합니다. 이는 데이터 전송 속도를 높이고,
전송 과정에서의 오버헤드를 줄여줍니다.

3. **컨텍스트 스위칭 오버헤드 감소:**


- DMA를 사용할 경우, CPU는 데이터 전송 작업을 DMA 컨트롤러에 맡기고, 다른 프로세스를 처리할
수 있습니다. 이는 빈번한 컨텍스트 스위칭으로 인한 오버헤드를 줄여줍니다. 반면에, 폴링을 사용할 경우
CPU가 지속적으로 상태를 확인해야 하므로, 컨텍스트 스위칭이 빈번하게 발생할 수 있습니다.

4. 시스템 반응성 개선:


- DMA를 사용하면 IO 작업이 비동기적으로 수행되어, CPU는 다른 작업을 계속 수행할 수 있습니다.
이는 시스템의 전반적인 반응성을 개선시킵니다. 폴링은 CPU가 특정 작업에 고정되게 만들어, 시스템 반
응성을 저하시킬 수 있습니다.

5. 낮은 CPU 오버헤드:
- 폴링은 CPU가 지속적으로 장치의 상태를 확인해야 하므로, CPU 오버헤드가 증가할 수 있습니다.
DMA는 이러한 오버헤드를 최소화하고, 효율적인 자원 활용을 가능하게 합니다.
+) polling이 사용되기에 적합한 상황
폴링(Polling)을 사용하는 것이 더 적합한 상황은 다음과 같습니다:

1. 장치의 속도가 빠르고 데이터 전송 시간이 짧은 경우:


- 장치의 데이터 전송 속도가 매우 빠르고, 데이터 전송에 소요되는 시간이 짧을 경우 폴링이 더 효율
적일 수 있습니다. 예를 들어, 매우 빠른 네트워크 장치나 고속 저장 장치의 경우 데이터 전송 작업이 매
우 짧은 시간 내에 완료될 수 있습니다. 이때, 폴링을 통해 상태를 확인하는 것이 DMA를 사용하는 것보
다 더 빠르고 간단할 수 있습니다.

2. 단순한 장치와 통신하는 경우:


- 통신 프로토콜이 단순한 장치나 작업이 간단한 경우 폴링이 적합할 수 있습니다. 간단한 센서나 작
은 데이터 패킷을 주고받는 장치는 폴링으로 충분히 관리할 수 있습니다. 이러한 경우, 폴링의 오버헤드
가 상대적으로 낮기 때문에 효율적일 수 있습니다.

3. 실시간 성능이 중요한 경우:


- 실시간 시스템에서 일정한 주기로 장치 상태를 확인해야 하는 경우 폴링이 유리할 수 있습니다. 예
를 들어, 실시간 제어 시스템에서는 주기적으로 장치 상태를 확인하고 즉각적인 반응이 필요할 때 폴링
이 더 적합할 수 있습니다.

4. DMA 설정 오버헤드가 큰 경우:


- 작은 데이터 전송 작업에서는 DMA 설정과 초기화 오버헤드가 폴링의 오버헤드보다 클 수 있습니
다. DMA는 설정 과정이 필요하고, 이 과정이 데이터 전송 시간보다 오래 걸릴 수 있습니다. 이 경우, 폴
링을 사용하는 것이 더 효율적일 수 있습니다.

5. 단일 태스크 또는 낮은 CPU 로드:


- 시스템에 실행 중인 태스크가 적고, CPU가 대부분의 시간을 유휴 상태로 보내는 경우 폴링을 사용
해도 큰 문제가 되지 않을 수 있습니다. CPU 로드가 낮다면, 폴링으로 인한 CPU 시간 낭비가 상대적으
로 적기 때문에 폴링이 유효한 옵션이 될 수 있습니다.

### 결론
폴링이 적합한 상황은 장치의 데이터 전송 속도가 빠르고, 작업이 간단하며, 실시간 성능이 중요한 경우
입니다. 또한, 시스템의 CPU 로드가 낮거나 DMA 설정 오버헤드가 큰 경우에도 폴링이 효율적일 수 있
습니다. 이러한 상황에서는 폴링을 사용하여 시스템의 복잡성을 줄이고 간단한 방식으로 장치와 통신할
수 있습니다.

You might also like