728x90
Disk Structure

Disk Structure

  • Magnetic Disk : HDD 등
    • Transfer Rate : 저장 장치 - 커뮤퍼 사이의 데이터 전송 속도
    • Positioning Time(random-access time) : 디스크 암이 목표 실린더에 도달하는 시간(seek time)과 목표 섹터에 도달하는 시간(rotational latency)
    • head crush : 디스크 암과 디스크가 맞닿는 현상
  • Access Latency = Average access time = 평균 탐색 시간 + 평균 지연
  • Average I/O time = average access time + (transfer amount / transfer rate) + controller overhead

  • Logical block
    • 디스크는 1차원의 logical block의 배열로 관리
    • 논리적 주소가 물리적 주소를 의미하지는 않음
    • garbage collector : 쓰레기 값이 저장된 block을 초기홫

Disk Scheduling

  • seek time의 최소화
  • request queue에 실린더 위치가 순서대로 입장
    • ex) 98, 183, 37, 122, 14, 124, 65, 67
    • head 위치는 53이라고 가정
  • FCFS : 큐에 들어오는 순서대로 접근
  • SSTF : 현 위치에서 seek time이 가장 짧은 위치로 먼저 접근
    • SJF와 유사 : starvation 문제가 생길 수 있음
  • SCAN : 디스크 암이 logical array의 양 끝 번갈아 왕복하며 처리
    • elevator algorithm이라고도 부름
    • 디스크 암과 실린더 위치에 따라 장시간 대기해야 하는 경우가 생길 수 있음
  • C-SCAN
    • 실린더의 처음부터 끝까지 순서대로 처리
    • 실린더 끝까지 탐색하면 다시 처음으로 이동한 뒤 끝까지 이동하면서 처리
    • 실린더 양 끝을 왕복하는 SCAN의 단점이 어느정도 해결
  • C-LOOK
    • Look : 큐의 최대/최소점에 도달하면 실린더는 반대 방향으로 탐색
    • C-Look : Look으로 동작하되, C-SCAN과 같이 큐 최대점 도달 시 다시 최소점으로 이동한 후 처리

Disk Management

  • Low-Level Formatting
    • 물리적 포맷이라고도 함
    • 디스크를 R/W 동작이 가능한 섹터로 분할
    • 각 섹터는 정보, 데이터, ECC(Error Correction Code)가 저장
  • 파티션 : 디스크를 논리적 단위로 분할
    • 논리적 포맷 혹은 "파일 시스템을 만든다" 라고도 함
    • 효율성을 위해 파일은 클러스터 단위로 처리 (디스크 > 블록, 파일 > 클러스터)
  • 부팅 과정
    • 롬에 저장된 BootStrap이 부팅 시 호출됨
    • 디스크 0번 섹터(MBR)의 프로그램이 부트스트랩을 호출하는 기능을 함(Bootstrap Loader)

  • Swap Space management
    • page 파일을 만들어 관리하거나, swap 파티션을 할당하여 관리
    • swap map : 커널은 swpap 사용 방식을 추적
    • swap 공간이 없다 = 메모리 가용량이 없음 >> process kill or crash

RAID

  • 저가의 디스크를 다수 연결하여 고성능 구현 (scale - out)
    • mean time to failure : 고장 확률이 높아짐
    • mean time to repair : 추가적인 고장 확률이 높음
  • 다수의 디스크를 병렬로 기록 시 : 읽는 속도가 증가
  • ex. 디스크의 mean time to failure = 100000, mean time to repair = 10
    • mean time to data loss = 100000^2 / ( 2 * 10 ) = 500 * 10 ^ 6 (약 57000년)
    • 실제로는 저장장치가 완전히 독립적이지 않으므로 이보다는 짧아짐

  • Disk striping : 여러 개의 저장 장치를 하나의 단위로 취급
  • RAID를 통해 성능을 높이거나, 저장장치의 신뢰성을 높일 수 있음
  • RAID 0
    • 큰 데이터를 각 저장장치로 분산
    • 디스크 중 하나가 고장나면 전체 데이터가 손실
  • RAID 1
    • Mirroring 혹은 Shadowing으로 호칭
    • 각 디스크의 복사본을 저장
    • 한 쪽이 고장나도 안전한 대체 가능
  • RAID 2 : ECC code를 사용
  • RAID 3 : Bit Interleaved Pairty
  • RAID 4 : Block Interleaved Parity / Parity disk가 고장 시 전체 데이터 손실
  • RAID 5 : RAID 4에서 parity를 각 디스크로 분산
  • RAID 6 : Parity 정보를 이중으로 기록
  • RAID 1 + 0 / RAID 0 + 1
    • 전자는 Striped Mirror, 후자는 Mirrored stripe
    • 신뢰성과 성능 모두를 추구
    • 디스크 구조상 RAID 1 + 0이 더 안전
  • hot-spare : 비상용 디스크 / RAID 중 디스크 고장 시 빠른 대체

Stable Storage Implementation

  • 데이터를 저장할 때 안전하게 보관하는 상태
  • 1개 이상의 비휘발성 저장소에 복원 가능하도록 데이터를 저장
  • Disk Write의 결과
    • 정상 작동
    • 부분 실패
    • 완전 실패
728x90
728x90
Virtual address

Virtual address

  • virtual address space : 프로세스 내의 주소 표현을 논리적으로 나타냄
    • 0으로 시작하여 연속적으로 표현
  • demand paging
    • 프로세스의 필요한 페이지만 필요할 때 할당하는 것
    • I/O가 덜 필요하거나 아예 쓸 필요가 없음
  • page fault
    • logical memory에서 page table 접근 시 invalid한 경우
    • 다른 page table을 참조하게 되는 경우

  • demand paging 단계
    • 레지스터와 프로세스 상태 저장
    • page fault로 인한 인터럽트 여부 확인
    • page table의 valid 여부, page 위치 확인
    • 저장소에서 frame으로 read 요청
      • 요청을 큐에 할당
      • 장치의 seek/latency time동안 대기
      • page를 free frame으로 전송
    • 대기 중일 때는 CPU는 다른 사용자에게 할당
  • demand paging 시의 EAT
    • 주된 동작 : 인터럽트 서비스, page read, process restart
    • page fault rate p를 가정 (p=0 : no page fault)
    • EAT = (1 - p) * 메모리 접근 + p * (page fault overhead + swap In + swap Out)

Copy on Write

  • 프로세스 fork 시 부모 - 자식 프로세스가 같은 page를 공유하게 하는 것
    • 자식 프로세스 생성 시에는 프로세스 공간을 복사하지 않음
    • 한 쪽의 프로세스가 write 동작 시 page 복사가 일어남
  • page replace
    • page의 과한 할당을 방지
    • page overhead를 줄이기 위한 modify(dirty) bit 사용 - 수정된 page만 write

Page replace

  • 제한된 메모리 상의 process 할당 시 page 전환이 필요
  • 여유 공간이 없을 경우 page를 전환하여야 함
  • page replace 단계
    • page 할당이 필요할 때, free frame을 탐색
    • free frame이 없을 경우, 제거될 frame(victim frame)을 선택
    • victim frame은 저장소로 swap out / 필요 데이터는 그 자리로 swap in
  • replace algorithm
    • frame - allocation : 프로세스당 프레임을 얼마나 할당할지, 어떤 프레임을 재할당할지
    • page - replacement : page fault rate를 최소한으로 하도록
    • reference string : 접근한 page 기록을 저장하여 replace 알고리즘에 사용
  • FIFO
    • 가장 먼저 들어온 page를 replace
    • page fault는 10번 발생 (처음부터 계속 page가 없어 replace함)
    • belady's anomaly : frame 수가 늘어나면 오히려 page fault가 많아질 수 있음
  • Optimal algorithm
    • 가장 오래 사용될 페이지는 유지
  • Least Recently Used(LRU)
    • 가장 사용되지 않은 데이터를 교체
    • 미래를 예측하는 Optimal과 달리 과거 데이터를 활용
  • second chance algorithm
    • FIFO와 유사
    • reference bit가 0이면 교체
    • reference bit가 1이면 0으로 변경
    • enhanced second chance
      • (reference, modify)로 2개 bit 할당
      • (0, 0) : replace
      • (0, 1) : replace 전에 메모리 write
      • (1, 0), (1, 1) : 다음 접근 시 replace
      • ex. (1, 1) > (0, 1) > (0, 0) - 3번의 반복을 통해 victim frame이 됨

Buddy System

  • 2n2^n allocater를 이용한 메모리 할당
  • Slab : 1개 이상의 연속된 page
    • 캐시는 하나 이상의 Slab로 구성
  • prepaging
    • page fault 방지를 위해 미리 page 할당
  • program 구조
    • 2차원 array int[a, b]를 가정
    • 각 row에는 page가 저장됨
    • 위 코드는 col마다 접근하기 때문에 a * b번의 page fault가 발생하나, 아래 코드는 page fault가 row 개수만큼만 발생
for(j=0;j<a;j++) for(i=;i<b;i++) data[i, j]=0 for(i=;i<b;i++) for(j=0;j<a;j++) data[i, j]=0
  • I/O Interlock
    • 프로세스가 I/O 장치를 접근할 때, 해당 프로세스가 swap되는 경우
    • 프로세스는 물리적 주소가 할당되기 전이지만, 데이터는 여전히 입력되어야 하는 상태가 됨
    • 이로 인한 문제를 방지하기 위해 프로세스의 해당 page를 swap되지 못하도록 함 (Pinning)
728x90
728x90
Address Binding
  • 실행된 프로그램은 메모리에 적재됨
    • 메모리에 적재되는 데이터 : 명령어, parameter, parameter가 저장된 주소
  • 메모리가 처리하는 data stream
    • read : address
    • write : address + data
  • 보통 레지스터 접근은 1 clock 내에 처리
    • 메모리 접근은 레지스터 대비 긴 시간이 걸리기 때문에, 중간에 캐시 메모리를 이용하여 병목 현상을 보완
  • 메모리 보호
    • 프로세스가 접근 가능한 주소에 제한
    • ex. 프로세스 할당 시 주소(base) 레지스터와 함께 할당 공간의 제한(limit) 레지스터를 같이 할당
    • base 아래 혹은 base + limit 위의 주소 접근 시 인터럽트를 호출하여 process 삭제

Address Binding

  • 프로그램 생성마다의 address binding 단계
    • 소스 코드 : 변수 주소를 symbolic하게 표현
    • 컴파일된 코드는 주소를 relocatable address로 bind
      • relocatable addreess : 프로그램 시작 지점에서의 상대적 offset 주소
    • 링커 / 로더 : 메모리에 적재된 프로그램에 실제 주소 할당
  • 주소가 결정되는 단계
    • compile time : 만약 이 단계에서 static한 주소 명시가 된 경우 compile 단계에서 주소 할당
    • Load time : compile time에서 할당되지 않은 주소를 relocatable address로 할당
    • Execution time : 실행 중 새롭게 할당되는 주소 관리

MMU(Memory-Management Unit)

  • Logical Address : 프로세스가 바라보는 주소, 가상 주소라고도 함
  • Physical Address : 메모리상의 실제 주소
  • CPU에서 명령 수행 시 logical address에 접근
  • MMU에서 logical address-physical address를 변환
  • simple scheme
    • MMU에는 relocation register에 값이 할당
    • CPU에서 logical address 접근 시, relocation register 값만큼 offset을 주어 physical address에 접근하게 함
    • ex. relocation register에 10000이 저장, CPU에서 ld 365 명령 실행 시 실제로는 10365 주소의 메모리에 접근
    • dynamic relocation : 만약 해당 주소에 접근 불가할 경우 relocation register 값을 변경

  • static linking
    • binary 코드 생성 시 라이브러리를 모두 포함
    • 프로그램이 무거워지고, 라이브러리가 중복 사용되는 경우 메모리 비효율성
  • Dynamic Linking
    • 중복 사용되는 라이브러리는 메모리에 미리 적재
    • 해당 라이브러리를 사용하는 프로세스는 필요할 때마다 별도로 호출
    • stub : Dynmic link를 찾는 루틴

Variable Partition

  • hole : 가능한 메모리 블럭
  • 프로세스를 단순히 연속 할당 시 메모리 관리가 비효율적이 될 수 있음
  • Dynamic Storage Allocation
    • First fit : 할당 가능한 첫번째 hole에 프로세스 할당
    • Best fit : 할당 가능한 최적의 hole에 프로세스 할당
    • Worst fit : 가장 큰 hole에 프로세스 할당
  • Fragmentation : 할당으로 인해 생기는 메모리 비효율
    • external fragmentation : 전체 메모리 여유 공간은 충분하나, 연속적이지 않아 할당이 불가능한 경우
    • internal fragmentation : 요청받은 프로세스 크기보다 할당 공간이 약간 큰 경우, 메모리 차이만큼의 공간은 너무 작아서 활용이 불가능
    • 50% rule : 메모리를 N개 block으로 할당한다고 할 때, 절반 가량은 fragmentation에 의해 사용 불가
  • Compactation : external fragmentation의 제거
    • 모든 hole을 하나의 공간으로 합침
    • relocation이 동적일 때, excution time에 동작함

Segmentation

  • 메모리를 segment라는 논리적 단위로 할당
  • segmentation 구조 : <segment-number, offset>
    • segment table : 각 segment의 base, limit 주소를 저장, segment number로 접근
      • base : segment의 시작 주소
      • limit : segment의 길이, 이 주소를 초과하여 접근시 error

  • segment number(s)는 segment table로 접근
  • offset은 segmnet table의 limit과 비교
    • limit 초과 시 addressing error
  • segment table의 base와 offset이 합쳐져 실제 메모리로 접근하게 됨

Paging

  • 메모리의 주소를 고정 크기로 나누어 할당하는 것
    • 연속적 할당이 아니므로 fragmentation 문제가 없음
  • frame : 물리적 메모리에 접근하는 block 단위
  • page : 가상의 메모리에 접근하는 block 단위
    • page 요청 > frame 요청 > OS는 빈 frame를 찾아 할당
  • addresss translation
    • CPU에 의해 생성되는 주소는 page number / offset으로 구분
    • page number : page table에 접근하기 위한 index >> frame number를 탐색하여 page offset과 조합
    • page offset : 실제 메모리 주소에 접근하기 위해 사용
    • page size를 4kb(2^12)라 가정
    • 32bit system에서 page offset d = 12가 되고, page number p = 20이 됨
  • CPU가 logical 접근
    • page table에 p index 값을 접근, 해당 값을 frame에 전달
    • offset d만큼의 주소를 더해 접근
    • frame offset d만큼의 주소를 더해 메모리 접근

  • internal fragmentation = page size - page 할당 후 남는 크기만큼
  • worst fragmentation = 1 frame - 1 byte
  • average fragmentation = frame size * 0.5
  • Page table
    • page table base register(PTBR) : page table 위치를 가리킴
    • page table length register(PTLR) : page table의 크기를 나타냄
  • TLB(Transition look-aside buffer)
    • CPU에서 메모리 접근 시 page table을 거치기 때문에 속도 문제가 발생
    • associative memory라고도 하며, 논리 - 물리 메모리 주소의 변환 결과를 미리 저장
    • TLB에 데이터 존재시(hit) 메모리 접근, 없을 경우 page table 접근
  • Effective Access TIme(EAT)
    • hit ratio : TLB에서 데이터를 찾아올 수 있는 비율 (ex. hit ratio 80% : 100번 탐색 중 80번은 TLB로 접근)
    • EAT = hit ratio * TLB access time + (1 - hit ratio) * memory access time
  • memory protection
    • page table에 read/write bit를 설정하여 프로세스 접근 시 읽기/쓰기 가능 여부를 설정
    • valid-invalid : 페이지가 프로세스의 주소 공간에 할당되었는지 여부를 확인

Page Table Structure

  • hirearchial page table
    • page table 탐색의 overhead 감소
    • page table의 page table을 구성
    • logical address는 inner page + outer page + offset과 같이 구성
  • hased page table
    • page table을 hash table로 구성
  • inverted page table
    • 논리 주소가 아닌 물리적 주소로 page table 구성
    • virtual address를 이용하여 shared page 구현

Swapping

  • 사용되지 않는 프로세스를 보조 저장장치에 저장하여 메모리를 관리
  • context switching time = 전송 시각 * process 크기 * 2
728x90
728x90
Deadlock

Deadlock

  • 데드락의 발생 조건
    • Mutual Exclusion : 프로세스 간 자원의 공유(동시 사용)이 불가
    • Hold and Wait : 자원을 한 프로세스가 점유한 경우, 다른 프로세스 접근 시 대기
    • No Preemption : 점유한 자원은 반환하기 전까지 해당 프로세스가 계속 사용
    • Circular wait : 프로세스는 다음 프로세스의 자원을 대기
      • Pa > Pb, Pb . Pc, ... Pz > Pa

  • Resurce Allocation Graph
    • 자원의 할당 방향을 표현
    • P : Process, R : Resource, T : Thread
    • 자원 요청 : P에서 R로 화살표
    • 자원 할당 : R에서 P로 화살표
    • R 내의 점 : Resource가 갖는 인스턴스를 의미
  • Circular wait에 의한 데드락 발생 조건
    • Cycle 없음 : deadlock x
    • Cycle 있음 : 리소스 내에 인스턴스가 복수개 있을 경우 deadlock x

Handling deadlock

Deadlock Prevention

  • Mutual Exclusion - 자원의 공유 허용
  • Hold and Wait
    • 프로세스 시작 전에 자원을 미리 할당
    • 자원을 미리 할당해야 하므로 활용성이 떨어지거나, starvation 위험
  • No preemption - 자원 선점 허용
  • Circular Wait - 자원에 lock 요청 시 우선순위 배정
void transaction(account from, account to, double amount){ mutex lock1, lock2; lock1 = get_lock(from); lock2 = get_lock(to); acquire(lock1); acquire(lock2); //from이 먼저 lock acquire withdraw(from, amount); deposit(to, amount); release(lock2); release(lock1); }

Deadlock Avoidance

  • 각 프로세스가 요구하는 자원 정보가 필요
  • 시스템이 deadlock 진입 여부를 확인한 후 자원을 할당
  • safe state : 자원 할당 시 deadlock이 발생하지 않는 상태
  • unsafe state : deadlock이 발생할 가능성이 있는 상태
  • avoidance algorithm
    • resource-allocation graph
      • 리소스당 인스턴스가 하나인 경우
      • Claim edge : 프로세스/스레드 할당 시 필요 자원을 OS에 요청
      • Claim edge > request > assignment > claim > ...
      • claim edge를 이용하여 요구 자원이 사용중인지 여부를 판단해 deadlock 방지
    • Banker's Algorithm
      • 리소스당 인스턴스가 다수 존재
      • 각 프로세스는 OS에 사용 자원을 알려야 함
      • 자원 부족시 대기
      • 프로세스 실행 후 일정한 시간 후 자원을 반납
      • banker's algorithm의 자료구조
        • available : 사용 가능한 인스턴스를 저장하는 vector
        • max : 리소스 당 사용 가능한 자원을 나타내는 matrix
        • allocation : 각 프로세스가 점유한 자원을 나타내는 matrix
        • Need : 프로세스 완료를 위해 필요한 자원을 나타내는 matrix
          • neet = max - allocation

  • safety algorithm
    1. 변수 선언
    • work = available
    • finish[i] = false: 프로세스가 끝났는지 여부
    1. i에 대해서
    • finish[i] = false
    • need[i] <= work인 프로세스 탐색
    • 존재하지 않는경우 4로
    1. 자원 반납
    • work = work + allocation
    • finish = true
    • 2 반복
    1. finish[i] == true인 경우, 시스템은 safe state
  • resource request algorithm
    • request_i[j] : 프로세스 i의 request vector
      • request_i[j]=k : 프로세스 i는 resource j의 k개 인스턴스를 필요로 함
    • request_i <= need면 진행, 그렇지 않은 경우 error(최대 제한을 초과)
    • request_i <= available이면 진행, 그렇지 않은 경우 자원 할당이 불가하므로 대기
    • 자원 할당
      • available = available - request
      • allocation = allocation + request
      • need = need - request
      • safe인 경우 자원 할당, unsafe인 경우 대기

Deadlock Detection

  • deadlock 감지 및 복구
  • wait-for-graph
    • resource allocation graph에서 resource가 빠진 방식
    • cycle 감지 시 n개 프로세스에서 n^2개의 계산 동작이 필요
  • detection algorithm
    1. 변수 선언
    • work = available
    • allocation_i != 0인 경우 finish_i = false, 그렇지 않은 경우 true
    1. i에 대해
    • finish[i] == false
    • request_i<=work인 프로세스 탐색
    • 존재하지 않는 경우 4로
    1. work = work + allocation, finish[i] = true, 2 반복
    2. finish[i] == false인 경우 i번째 프로세스는 deadlock

Deadlock recovery

  • deadlock된 모든 프로세스를 제거
  • deadlock이 풀릴때까지 프로세스를 하나씩 제거
  • 프로세스를 rollback
    • rollback당한 프로세스는 starvation 위험이 존재
728x90
728x90
Background

Background

  • Data consistency
    • 멀티프로세싱/스레딩 시에 다수 작업이 동시에 시행
    • 인터럽트 발생 시 이전에 동작하던 작업이 일시 중단되고 새로 실행
    • 여러 작업이 데이터를 공유할 경우 문제 발생
      • 데이터 업데이트 중 다른 프로세스가 읽어들이거나
      • 여러 프로세스가 동시에 쓰는 경우
    • 일정 루틴에 맞는 프로세스 실행 순서를 정의할 필요가 존재
  • Producer - Consumer Problem
    • 데이터 생산 프로세스(Producer)는 큐가 차있지 않은 동안 데이터를 입력
    • 데이터를 쓰는 프로세스(Consumer)는 큐가 비어있지 않으면 데이터 사용
    • Counter 변수를 같이 접근하는 문제 존재
      • ++, --명령어 실행 시 변수값을 각 레지스터로 이동하여 처리
    • race condition : 초기값이 5일 때, 동시에 접근 시 Producer는 5 > 6, Consumer는 5 > 4로 Counter 값을 바꾸므로 결과적으로 카운터값이 6>4로 변경될 가능성 존재
    • fork()의 race condition
      • fork 실행 시 반환값은 PID
      • 두 프로세스가 동시에 fork 호출 시 같은 PID를 갖는 두 프로세스가 생성될 수 있음
/* Producer Process */ while (true) { /* produce an item in next produced */ while (counter == BUFFER_SIZE) ; /* do nothing */ buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE; counter++; } /* Consumer Process */ while (true) { while (counter == 0) ; /* do nothing */ next_consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; counter--; /* consume the item in next consumed */ }

Critical-Section Problem

  • 다수의 프로세스/스레드 생성 시 한 번에 하나의 작업만 실행될 수 있는 구간
    • 공용 데이터 접근시의 충돌 방지
do { /* Ask Permission to enter critical section */ /* Critical Section */ /* Exit Critical Section */ ... }while(...);
  • Critical Section 문제의 해결 조건
    • Mutual Exclusion : 프로세스 P가 Critical Section에 접근 시 다른 프로세스는 해당 구간을 실행하면 안됨(Critical Section의 정의)
    • Progress : Critical Section에 실행 중인 프로세스가 없을 경우, 이 구간에 진입하고자 하는 프로세스를 지연 없이 진입시켜야 함
    • Bounded Waiting : 프로세스 A가 Critical Section에 있을 때, 새 프로세스가 진입하고자 할 경우 A가 끝나는 것을 대기해야 하나, 무한정 대기해서는 안됨 (Critical Section 진입 시 우선순위의 조정 필요)
  • OS의 Critical-Section Handling : Non-Preemptive
    • 인터럽트 없이 커널 설계
    • 구현이 쉽고, 오류를 신경쓸 필요성이 낮아짐
    • 공유 데이터 접근 시 우선한 작업이 처리되어야 나머지 처리가 가능하므로 시스템 반응성, 성능이 떨어지게 됨

Peterson's Solution

  • SW 기반으로 HW 영역의 문제를 해결하고자 하는 접근법
  • 2개 프로세스/스레드를 가정
    • load/store 명령어는 순서대로 실행된다고 가정(각 명령어 중에는 인터럽트가 없음)
    • 두 프로세스에는 변수가 존재 : int turn ; bool flag[2]
    • turn : critical section에 접근 가능한 프로세스
    • flag[i]가 true면 i번째 process가 Critical section에 접근하고자 함
  • Entry Section
    • 자신의 flag를 true로 만듦 : critical section에 접근할 준비
    • turn을 상대 프로세스 값으로 대입
    • while : 상대 프로세스가 준비가 되었고(flag), 실행할 순서인 경우(turn), 완료할 때까지 무한루프로 대기
      • 그렇지 않은 경우 자신의 코드 실행
    • critical section 실행 후 자신의 flag를 false로 설정
  • 위 예시의 검증
    • Mutual Section : while문 조건에서 turn이 상대방 값으로 대입되므로 critical section에 동시 접근이 불가
    • Progress : Entry section에 진입하지 않은 경우 해당 프로세스의 flag는 false이므로 다른 프로세스는 바로 critical section에 접근 가능
    • Bounded Waiting : turn이 상대 값으로 대입되었기 때문에 프로세스가 while문 재진입 시 다른 프로세스에 우선권을 넘겨주므로 무한 대기 없이 두 프로세스가 순차 실행

  • Peterson's Soultion의 문제 : 현대 컴퓨터에서 실행을 보증하지 않음
    • 프로세서나 컴파일러가 성능을 위해 독립적으로 실행되는 명령어 순서를 변경할 수 있음
    • 독립적인(서로 다른 곳에 접근하는) 명령어의 경우 순서를 바꾸어도 결과는 동일
    • 멀티코어 / 멀티프로세서 구조에서 심각한 문제가 될 수 있음
      • 원래의 알고리즘
        • (Process i) flag i = true, turn = j
        • (Process j) flag j = true, turn = i
        • (Process j가 먼저 접근한 경우) j는 critical section 처리, i는 while 대기
        • flag j = false : Process i가 critical section 처리
      • 현대 아키텍처의 경우
        • (Process i) turn = j : flag를 나중에 대입
        • (Process j) turn = i, flag j = true
        • turn i=false이므로 Process j가 Critical section 처리
        • (Process i) flag i = true
        • turn이 i이므로 Process i도 Critical Section에 접근 가능 : Mutual Section 위반

HW Support for Synchronization

  • Critical Section Code를 위한 별도 명령어 제공
    • Memory Barrier
    • HW Instruction
    • Atomic Variable
  • Memory Barrier
    • 명령어의 실행 순서를 명시
    • Strongly Ordered : 각 프로세서가 구현 명령어대로 접근
    • Weakly Ordered : 명령어 접근 순서가 바뀔 수 있음
    • Memory barrier : 배리어 전후로는 명령어 순서 변경이 불가
  • HW Instruction
    • Test-and-Set

      boolean test_and_set (boolean *target) {
      boolean rv = *target;
      *target = true;
      return rv:
      }

      • 다른 명령어와 독립적으로 실행(execute atomically)
      • target값을 읽어들인 후, target에 새 값 대입
      • 읽어들인 값 rv 반환
    • Compare-and-Swap

      int compare_and_swap(int *value, int expected, int new_value) {
      int temp = *value;
      if (*value == expected)
      *value = new_value;
      return temp;
      }

      • 이전값(value)가 예측값(expected)와 동일하면 새 값(new_value)로 치환
// criticals section with test_and_set do { while (test_and_set(&lock)) ; /* do nothing */ /* critical section */ lock = false; /* remainder section */ } while (true);
  • test_and_set이 처음에는 false
    • 먼저 접근한 프로세스가 lock을 true로 바꿈
    • 나머지 프로세스들은 test_and_set이 true를 반환하게 되므로 mutual section이 성립
//critical section with comp_and_swap while (true){ while (compare_and_swap(&lock, 0, 1) != 0) ; /* do nothing */ /* critical section */ lock = 0; /* remainder section */ }
  • 초기값 lock이 0이면 해당 프로세스는 Critical section 진입하면서 lock을 1로 바꿈
    • 나머지 프로세스는 lock이 1이므로 while 대기
    • 이때 value와 expect가 다르므로(1, 0) swap이 되지 않게 됨
while (true) { waiting[i] = true; key = 1; while (waiting[i] && key == 1) key = compare_and_swap(&lock,0,1); waiting[i] = false; /* critical section */ j = (i + 1) % n; while ((j != i) && !waiting[j]) j = (j + 1) % n; if (j == i) lock = 0; else waiting[j] = false; /* remainder section */ }
  • Bounded waiting and Mutual section
    • i번째 프로세스가 실행된 경우
    • i+1부터 순회하면서 대기중인 프로세스 탐색
    • 대기중인 프로세스가 있을 경우 해당 프로세스의 waiting 상태를 풀어줌
    • 특정 프로세스가 계속해서 점유하는 것을 방지
  • Atomic Variable
    • 변수 하나만을 보호해야 할 경우
    • 동시 접근 시 데이터의 일관성 보장

Mutex Locks

  • acquire/release 명령어로 atomic variable 선언
    • busy wait : Critical Section에 접근하지 못한 나머지 변수들은 while loop를 돌면서 대기
    • spin lock : 무한루프를 돌면서 대기하는 형태(busy wait)

Semaphores

  • Mutex Lock의 경우 한 번에 하나의 프로세스만 Critical Section 진입
  • Semaphore의 경우 정수 변수 S 값의 설정에 따라 진입 가능한 프로세스 수 설정 가능
    • wait(S) : 대기 중인 프로세스 조정
    • signal(S) : 실행이 완료된 프로세스 release
  • 자원 관리에 주로 사용
  • Busy wait이 없는 Semaphore
    • 프로세스 sleep(), wakeup() 확인
    • wait : 프로세스 실행이 불가능한 경우 프로세스를 sleep queue에 추가 후 sleep
    • signal : 프로세스가 추가 실행이 불가능하면서 waiting중인 프로세스 존재 시 해당 프로세스 wakeup
    • 프로세스 리스트 접근 시 mutex section 구현 필요
wait(semaphore *S) { S->value--; if (S->value < 0) { //add this process to S->list; block(); } } signal(semaphore *S) { S->value++; if (S->value <= 0) { //remove a process P from S->list; wakeup(P); } }

Monitor

  • mutex/semaphor의 고레벨 구현
  • monitor 내에 선언한 함수는 컴파일 단계에서 wait-signal이 구현됨
  • condition variable
    • 변수에 여러 프로세스가 동시 접근 시 signal - wait 구현

Liveness

  • Progress, Bounded Waiting으로 보장
  • 프로세스가 일정 시간 내에 실행되는 것을 보장
    • 보장되지 않을 경우 알 수 없는 이유로 시스템이 멈추는 등의 문제 발생
  • Deadlock
    • 둘 이상의 프로세스가 서로의 자원을 필요로 하는 상황
    • 서로의 wait을 위해 서로의 자원을 필요로 하는 상황
      • P0의 Q wait을 위해서는 P1이 대기하는 Q가 필요
      • P1의 S wait을 위해서는 P0이 대기하는 S가 필요
  • Starvation
    • 프로세스가 공유 자원(Critical Section, Semaphore, ...)을 무한히 대기하는 현상
    • 선점한 프로세스가 무한히 자원을 점유하기 때문에 발생
  • Priority Inversion
    • P1>P2>P3의 우선순위를 갖는 프로세스(P1이 가장 우선)을 가정
    • P1, P3이 공유 자원 R1을 사용하는 상황
    • P3이 사용하는 자원을 release해야 P1을 실행 가능
    • 이때 P2가 실행되면 P2>P3이므로 P2가 우선 실행
    • P1은 R1 자원을 대기중이므로 실행되지 못함
    • 이로 인해 P2가 P1보다 우선 실행되는 우선순위 역전 현상이 발생
    • 해결책 : Priority Inheritance(우선순위 상속) - P3의 우선순위를 P1 수준으로 높여줌

Bounded-Buffer Problem

  • n개의 버퍼마다 데이터 존재
    • 버퍼에는 full, empty, mutex 변수를 갖고 있음
    • full : 버퍼 내 데이터 수
    • empty : 버퍼 내의 공백 수 (full + empty = 버퍼 크기)
    • mutex : 프로세스의 권한 할당 여부 (1 - producer / 0 - consumer)
  • Producer
    • 버퍼가 비었는지 확인(wait(empty))
    • lock acquire - release acquire(wait, signal(mutex))
    • notify consumer(signal(full))
  • Consumer
    • 버퍼가 찼는지 확인(wait(full))
    • lock acquire - relase acquire(wait, signal(mutex))
    • notify producer(signal(empty))

Readers-Writers Preoblem

  • readers : 데이터를 읽기만 하는 프로세스
  • writers : 데이터의 입/출력을 모두 하는 프로세스
  • readers의 경우 동시에 데이터 읽기가 가능하게 설정
    • rw_mutex semaphore를 설정
728x90
728x90
CPU scheduler

CPU scheduler

  • ready queue 내의 프로세스를 선택하는 방식
  • CPU 스케줄링 이 동작하게 되는 프로세스의 경우의 수
    • running > waiting
    • running > ready
    • waiting > ready
    • 프로세스 제거
    • 1, 4의 경우 non-preemptive / 2, 3은 preemptive scheduling
  • Dispatcher
    • 기존 프로세스의 상태를 PCB에 저장/불러오기
    • dispatch latency - dispatcher가 프로세스를 중단하고 다른 프로세스를 실행하기까지의 시간

Scheduling criteria

  • 스케줄러의 성능 요인
    • CPU utilizationn : 가능한 CPU를 최대로 사용
    • Throughput : 시간당 사용 가능한 프로세스 수
    • Trunaround time : 프로세스가 실제 실행될때까지의 시간
    • waiting time : 프로세스가 ready queue에서 대기하는 시간
    • response time : request 요청에서 실제 응답까지의 시간
  • FCFS(first come, first served)
    • 프로세스가 진입하는 순서대로 처리
    • process : burst time 가정
      • P1 : 24 / P2 : 3 / P3 : 3
    • 간트 차트 : 프로세스의 시작 / 종료 시간을 표현
      • ex. P1, P2, P3 순 진입
        • P1의 대기시간 = 0 (즉시 시작)
        • 평균 대기 시간 = (0+24+27) / 3 = 17
      • P2, P3, P1 순 진입
        • P1의 대기 시간 = 6
        • 평균 대기 시간 = (0+3+6)/3 = 3
    • FCFS의 단점 : convoy effect
      • burst time이 긴 프로세스 진입 시 다른 작업도 크게 지연
  • SJF(Shortest Job First)
    • burst time이 짧은 작업 먼저 : wating time이 가장 짧음
    • burst time을 알아야 하는 문제 존재
      • 시스템의 burst time 예측 방법 : 이전 process 실행 기록을 통한 예측
        • τn=1=αtn+(1α)τn\tau_{n=1}=\alpha t_n+(1-\alpha)\tau_n
        • tnt_n : 실제 burst time
        • τn\tau_n : 이전에 예측했던 burst time
        • 0α10\leq\alpha\leq1(보통 0.5)

  • SRTF : SJF의 preemptive version
    • 먼저 동작한 프로세스가 동작 중
    • 새로운 프로세스 동작 시 남은 시간보다 새 프로세스 시간이 짧은 경우 이전 프로세스를 중단하고 새 프로세스 처리
  • Round Robin
    • 각 프로세스에 time quantum (q) 부여
    • 모든 프로세스의 대기 시간은 (n-1)q 이하
    • timer interrupt : 일정 시간이 지나면 다음 프로세스를 위해 발생
    • q가 매우 커짐 - FIFO / q가 매우 작아짐 - 프로세스 전환을 위한 overhead 과다
    • SJF 대비 turnaround는 크지만, response는 좋은 편

  • Priority Scheduling
    • 우선순위 순으로 처리
    • 우선순위가 낮은 프로세스가 실행되지 않을 수 있음(Starvetion)
      • 해결책 : Aging - 시간에 따라 프로세스 우선순위를 높임
  • Multilevel Queue
    • 우선순위가 다른 프로세스들의 배치
    • 우선순위에 따라 real-time, system, interactive, batch process queue로 나누어 할당
    • multilevel feedback queue
      • 프로세스가 처리에 따라 다른 큐로 옮겨질 수 있음
      • ex. 높은 우선순위 큐에서 다 처리되지 못한 경우, 한 단계 낮은 큐로 이동하여 처리

Thread Scheduling

  • 스레드는 user-level, kernel-level로 나뉘어짐
  • Many-to-one, Many-to-many의 경우 스레드 라이브러리가 동작시킬 유저 스레드를 관리
    • PCS(Process-Contention Scope) : 유저 스레드 간의 스케줄링
    • SCS(System-Contention Scope) : 커널 스레드간의 스케줄링
  • Pthread : 스레드 라이브러리, PCS/SCS 스레드 생성을 관리
    • 리눅스, MACOS의 경우 SCS로만 생성 가능

MultiProcessor Scheduling

  • Symmetric Multiprocessing(SMP)
    • common ready queue : global한 ready queue의 프로세스 하나를 각 코어에 나누어 할당
    • per-core run queues : 각 코어가 별개의 프로세스 할당
  • 최근에는 한 프로세스에 여러 코어가 할당(멀티코어 프로세스)
    • 멀티스레드 / 하이퍼스레딩
      • 각 코어에 1개 이상의 HW 스레드 할당
      • 한 스레드는 연산(compute)와 메모리 접근(memory stall)을 번갈아 처리
      • 멀티스레딩을 이용, 한 스레드가 memory stall할 때 다른 스레드로 전환하여 compute
    • 멀티스레딩의 고려점
      • SW상의 스레드는 OS를 통해 HW 스레드로 할당
      • 코어는 각 HW스레드를 나누어 처리
  • Load Balancing
    • SMP의 경우 모든 CPU가 효율적으로 작업 분배를 할 필요 존재
    • Push migration : 각 프로세스 작업을 확인해 특정 프로세스에 작업이 몰릴 경우 다른 프로세스로 분배
    • Pull migration : 작업이 없는 프로세스가 다른 프로세스 작업을 가져와서 처리(work stealing)
  • Processor Affinity
    • 어떤 프로세서에 할당하냐에 따라 작업 속도가 달라질 수 있음
    • soft affinity : OS가 특정 스레드가 특정 프로세스에 작업할 수 있게 제안 (반드시 동작하지는 않음)
    • Hard affinity : OS가 특정 프로세스에 affinity가 있는 스레드를 할당시킴
    • ex. CPU cache : CPU 캐시의 접근속도가 메모리 대비 매우 빠르기 때문에, 직전에 작업했던 프로세스에 계속 할당시켜 주는 것이 다른 프로세스에 할당하는 것보다 더 빠름
    • ex2. NUMA architecture : multi CPU - memory가 물리적으로 분리된 환경 - 간접적 연결보다 직접적으로 연결된 CPU-memory의 처리가 훨씬 빠르게 나타남

Real-Time CPU scheduling

  • realtime schedule의 경우 적정 시간 내에 동작하지 못할 경우 실패로 처리
  • soft real-time : 작업이 매우 높은 우선 순위를 갖고 실행
  • hard real-time : 작업은 반드시 적정 시간 내에 실행
  • Event latency : event가 발생 후 작업에 들어가기까지의 시간
    • Interrupt Latency : 인터럽트 종류 파악 - Context Switch - ISR 접근까지의 시간
    • Dispatch Latendcy : 프로세스가 가능한 상태가 된 후(인터럽트 직후) 프로세스 실행까지의 시간
  • Priority-based scheduling
    • 프로세스가 주기적 시간 p마다 들어온다고 가정
    • 프로세스 실행까지의 제한 시간(deadline) d를 가정
    • 프로세스의 처리 시간을 t로 가정
    • 0tdp0\leq t\leq d\leq p여야 함
  • Rate Monotonic Scheduling
    • rate p가 짧을수록 빠른 처리
    • 우선순위가 낮은 작업 중 높은 작업 진입 시 일시 정지 후 처리
    • 프로세스 작업 중 같은 프로세스가 재진입 시 deadline miss로 실행 실패
      • 실행 중이던 프로세스는 처리 시간을 모두 마치지 못해 실패
      • 새로 들어오는 프로세스는 설계에 따라 다름
        • 먼저 실행중인 프로세스가 우선한 경우 이전 프로세스에 의해 실행 deadline을 마치지 못해 실패
        • 새 프로세스가 우선하는 경우 계속 동작 (이전 프로세스만 실패)
    • EDF(Earliest Deadline First)
      • deadline이 짧은 프로세스를 우선

OS scheduling

  • Linux
    • 선점형, 우선순위 기반
    • 우선순위 기준 : 시분할, real-time은 별도로
    • 우선순위 변수 : nice (100 ~ 140) - nice to process, 낮을수록 우선
    • CPU별로 run queue를 할당
  • Windows
    • 우선순위 기반의 선점형
    • real-time class를 별도 할당
    • 0번 우선순위 : 메모리 관리

Algorithm Evaluation

  • little's law
    • 평균 큐 길이 n, 평균 대기 시간 W, 평균 arrival rate λ\lambda일 때,
    • n=λ×Wn=\lambda\times W
  • Simulation
    • 제한된 queue model
    • 각 모델을 직접 동작시키면서 성능 통계를 계산
728x90
728x90
Multicore Programming

Multicore Programming

  • 스레드 : CPU 활용을 위한 기본 단위
    • 멀티프로세스의 단점 : 동일 기능의 각 프로세스마다 code, data, file을 각각 할당하므로 처리 부담 증가
    • multithread
      • 프로세서 내의code, data, file은 공유한 상태로 레지스터, 스택, PC 등은 나누어 할당
      • 멀티프로세싱 대비 연산 비용이 적음
      • 같은 프로세스 자원을 공유하므로 shared memory / message passing보다 자원 공유가 쉬움
  • Multicore programming 시 고려할 점
    • 작업 분할, 데이터 분할, 데이터 의존성
    • 불완전할 시 프로세스 간 데이터 의존으로 인해 속도 저하
  • Concurrency / Parallelism
    • Concurrency : 다수의 작업이 동시에 수행(시분할)
      • 단일 코어에서 task 1, task 2, task 3...을 번갈아가며 조금씩 처리
    • Parallelism : 다수의 작업이 동시에, 독립적으로 수행
      • 코어 1 : task 1 / 코어 2 : task 2 ...
      • data parallel : 동일 데이터를 분할, 각 코어가 동일한 동작 수행 (ex. 1~100까지 더할 때 1~25 / 26~50 / ... 로 연산 데이터를 나눔)
      • task parallel : 작업을 분할하여 각 코어에 할당
  • Amdahl's Law
    • 동시성 프로그래밍으로 얻을 수 있는 성능 향상
    • speedup[S+1SN]1speedup\leq[S+\frac{1-S}{N}]^{-1} ( S : 병렬화 불가 부분, N : 코어 수 )
      • ex. S=25%, N=2 >> speedup은 최대 약 1.6배
      • 코어 N이 무한히 증가 >> 속도는 1/S로 수렴

Multithread model

  • 스레드의 종류
    • User thread : POSIX, window, java thread library
    • Kernel thread
  • Many-to-One
    • user thread : kernel thread = N:1
    • 멀티코어에서도 각 스레드가 병렬 처리되지 않을 수 있음
    • 구현이 쉬움
    • Ex. Solaris, GNU
  • One-to-One
    • user thread : kernel thread = 1:1
    • 병렬 처리 가능, 높은 동시성
    • 높은 Overhead : kernel thread가 많이 할당되어야 함
  • Many-to-Many
    • user thread : kernel thread = N:M
    • 구현이 복잡하여 최근에는 잘 쓰이지 않음
  • two-level : 여러 multithread model을 혼합하여 사용

Thread Library

  • Pthread
    • POSIX 표준에 따른 스레드 생성 및 동기화 API
      • POSIX API는 실제 구현이 아닌 동작 방식만 나타냄
    • UNIX 계열 OS에서 사용
  • Java Thread
    • JVM에 의해 관리
    • thread class의 extend 혹은 Runnable 인터페이스의 implement로 스레드 생성

Implicit Thread

  • Thread 구현에 필요한 노력을 경감
  • Thread Pool
    • 일정량의 스레드를 미리 생성
    • Pool 내의 빈 스레드에 작업 할당
    • 예측 가능한 범위 내에서 스레드 동작 가능
  • Fork-Join
    • 분할-정복법
    • 여러 개의 thread로 나눈 후(fork), 스레드 종료를 대기(join)
  • OpenMP
    • C, C++, 포트란의 컴파일러 명령어와 API
    • #pragma omp parallel로 병렬 처리가 가능한 부분을 선언
#pragma omp parallel for for(i=0;i<N;i++) { c[i] = a[i] + b[i]; // fork-join 방식으로 각 스레드에 0~N의 구간을 나누어 처리 }

Threading Issue

  • 스레드 fork와 exec
    • 프로세스 내의 한 스레드에서 fork > 새로운 프로세스 생성
      • fork 시 복사된 프로세스에는 해당 스레드만 유지하거나, 모든 스레드를 같이 복사할 수 있음
    • exec 호출 : 호출한 main thread 외에는 kill
  • Signal Handling
    • Signal : Linux/Unit의 프로세스 이벤트
      • 인터럽트가 HW적 event라면, Signal은 SW적 Event
      • Signal Handler가 Signal을 전달
      • dehault handler : Process 생성 시 같이 생성
    • Signal의 전달 방식
      • 시그널이 발생한 스레드에 전달
        • memory violation, divide by zero 등
        • Synchronous Signal : 발생한 스레드가 명확한 Signal
      • 프로세스 내의 모든 스레드에 전달
        • Crtl+C 명령어(Linux의 강제 종료 명령어) 등
      • 특정 스레드에 모든 시그널 전달
    • 스레드 동작 시 시그널 유발
      • 시그널을 처리하기 위해 bitmask 사용 (시그널을 처리할 / 하지 않을 스레드 지정)
  • Thread Cancellation
    • 외부에서 스레드를 강제 종료
    • Asynchronous cancellation : 모든 target thread를 즉시 삭제
    • Deferred cancelation : 스레드가 삭제 가능할 때 제거
      • 스레드가 중요 자료를 접근하고 있을 때 삭제 시 문제를 방지하기 위함
      • 기본 cancellation type
  • Thread - Local Storage
    • TLS라고도 함
    • 멀티스레드는 같은 메모리를 참조
    • Local 변수는 함수 내에서만 선언
    • TLS는 특정 스레드 내에서만 사용
  • Scheduler Activation
    • M:M thread model의 Issue
    • Lightweight Process(LWP) : 가상의 process를 통해 user - kernel thread 연결
      • upcall : kernel thread를 갖고 있는 LWP가 user thread에 할당된 경우, 새 LWP를 호출하여 해당 문제를 해결
728x90
728x90
Process

Process

  • Batch system의 Job / 시분할 시스템의 task, program
  • Process : 실행 중인 프로그램
    • 실제 코드 (text section)
    • program counter : 현재 상태 추적
    • 데이터 저장 및 함수 호출을 위한 메모리 스택, 힙
  • OS의 system call로 프로세스의 생성/삭제 구현
  • 메모리 상의 프로세스 할당
    • 시작 위치에는 text 저장(작성된 코드)
    • 그 위에 data(const, global 변수)
    • 그 위에 heap(malloc 등의 동적 할당)
    • stack : 지역 변수 / 함수 call
    • text, data, heap은 주소값이 작은 > 큰 쪽으로 할당
    • 스택의 경우 주소값이 큰 > 작은 쪽으로 할당
  • 프로세스 상태
    • new : 프로세스 생성
    • running : 명령 실행
    • waiting : 특정 이벤트 전까지 대기
    • ready : 프로세서에 할당되기 전의 대기 상태
    • terminated : 프로세스 삭제

  • Process Control Block(PCB)
    • task control block이라고도 함
    • 각 프로세스에 대한 정보 저장
      • 프로세스 상태
      • program counter : 다음 명령어의 위치
      • 프로세스의 우선 순위
      • 메모리 정보
      • 사용된 CPU, 클락 등의 정보
      • 프로세스에 할당된 I/O, 파일 정보
    • process간의 교환 : Interrupt 혹은 System Call로 이루어짐

  • Threads
    • 한 프로세스당 여러 개의 program counter 할당
    • 스레드 정보를 저장 가능한 공간 필요
      • ex. linux task_struct
    pid t_pid; /* process identifier */ long state; /* state of the process */ unsigned int time_slice /* scheduling information */ struct task_struct *parent; /* this process’s parent */ struct list_head children; /* this process’s children */ struct files_struct *files; /* list of open files */ struct mm_struct *mm; /* address space of this process */

Process Scheduling

  • CPU 활용을 최대한으로 하는 것이 목적
  • Queue 자료구조를 이용하여 관리
    • Job queue : 시스템 내 모든 프로세스
    • ready queue : ready / waiting 상태의 프로세스
    • device queue
      • 각 장치별로 queue head 존재
      • 프로세스가 device 사용 요청 시 해당 queue에 PCB가 연결
  • 프로세스의 동작 순서
    • 생성된 프로세스는 ready queue로 할당
    • 동작하는 프로세스는 CPU로 이동
    • I/O request 시 > I/O queue 할당 후 I/O 접근
    • time slice expire > ready queue 할당 후 CPU 할당
    • child fork / interrupt > 작업 후 ready queue 할당
  • scheduler
    • 프로세스가 I/O를 많이 쓰는지, CPU를 많이 쓰는지를 판단(I/O bound, CPU bound)
    • short term(CPU scheduler)
      • 현재 프로세스 바로 다음에 할당할 프로세스 선택
    • Long term(job scheduler)
      • 데이터센터 등 대형 시스템에서 사용
      • 다수의 작업을 모아서 한번에 효율적으로 처리
  • Context Switch
    • 프로세스 상태를 저장하고 새 프로세스로 전환
    • 상태를 저장 - 불러오고 새로 실행하는 과정의 overhead가 매우 큼
      • 파일 입/출력을 많이 하는 프로그램이 느린 이유

Operations on Process

  • Process Create
    • 부모 프로세스는 자식 프로세스를 생성
      • 트리 자료구조를 형성
      • 부모 프로세스는 자식 프로세스의 관리 가능(권한, 공유 등)
      • 부모-자식 프로세스의 동시 동작시 대기 혹은 병렬 처리 가능
    • 새 프로세스 생성 시, 부모 프로세스를 복사 후 프로그램 실행
      • UNIX의 프로세스 생성 명령어 - fork()
      • 자식 프로그램은 exec()명령어로 프로그램 실행
      • 부모 프로세스 wait : 자식 프로세스가 종료할 때까지 대기
  • Process Terminate
    • 완료 시 exit 후 상태 데이터를 반환
    • 자원을 과도하게 사용하는 등 프로세스 종료가 필요할 경우 abort()도 가능
    • cascading termination : 부모 프로세스가 먼저 종료시 하위 프로세스도 종료
    • 자식 프로세스가 사라져도 자원 회수 등을 위해 PCB는 여전히 존재
      • 부모 프로세스는 wait()으로 exit될 때까지 대기해야 함
      • wait 없이 프로세스 종료 시 : Zombie Process
      • wait 없이 부모 프로세스 종료 시 : Orphan Process

interprocess communication

  • 프로세스 간의 정보 교환
  • 교환 모델
    • message passing : 커널에서 제공하는 메세지 큐를 이용한 정보 교환
    • shared memory : 프로세스 간 공유 공간 할당
    • Producer-Consumer Problem
      • 데이터의 생산자(Producer)와 소비자(Consumer) 관계
      • 버퍼를 한정할지(bound), 안할지(unbound)의 문제
  • Shared memory
    • 통신하고자 하는 프로세스 간에 공유하는 메모리
    • OS가 아닌 사용자 level에서 통신 조절
    • 같은 메모리에 다른 프로세스가 동시에 조작 시 문제 존재
    • 프로그래밍이 어려우나
  • Message Passing
    • send / receive를 이용하여 프로세스 간에 데이터 전송
    • 프로세스 간의 링크 설정 필요
    • 2개 이상의 프로세스 연결 / 통신 방향(단방향, 쌍방향) 등을 고려

  • direct Communication
    • 데이터를 받을 프로세스 명시 send/receive(process, message)
    • pid가 바뀔 경우 접근 불가
  • Indirect Communication
    • mailbox(port)를 이용한 데이터 공유
    • 같은 process 연결에서 여러 개의 link 형성 가능
    • mailbox 생성 > 데이터 교환 > mailbox 삭제 과정으로 진행

  • Synchronization
    • Blocking : 데이터 송신 / 수신 중 한쪽이 끝날때까지 다른쪽은 불가
    • non-blocking : 송/수신에 제한 x, 오류 방지를 위해 데이터가 없는 경우 return 등으로 다른 행동을 하기 위한 별도 조치 필요
  • Buffering : 링크 사이의 메세지 큐
    • zero cap. : 큐 용량 x, 송/수신 중 하나가 끝나야 함
    • bound cap. : 정해진 용량, 큐가 모두 차면 대기
    • unbound cap. : 중단 없이 전송 가능

IPC system

  • POSIX
    • 통신할 각 process 내에 shared memory 생성
    • map 된 메모리에 메세지 작성(sprintf)
    • 받는 쪽은 해당 주소에서 데이터를 읽어옴
  • Windows
    • LPC(local procedure cell) : 일종의 mailbox
    • client - server 사이에 connect port(연결 요청)
    • client/communication port(일종의 양방향 통신, message passing)
    • shared section object(공유 메모리 역할)
  • Remote Procedure Call
    • 상대방 프로세스로 특정 동작을 요청
    • Stub : 두 프로세스 사이에 서로 다른 parameter, return 규칙을 알맞게 변환
    • Matcmaker : 프로세스 연결을 위한 Port 지정
  • Pipe
    • 부모 - 자식 프로세스 간의 데이터 교환
    • pipe라는 파일 객체로 데이터 관리
    • fd[0] : write / fd[1] : read
    • named pipe : 부모-자식 관계와 무관하게 통신
728x90
728x90
OS Services/Interface

OS Services/Interface

  • OS의 기능
    • 사용자 관점
      • User Interface(UI) : CLI, GUI, 터치스크린, Batch 등
      • 프로그램 실행
      • I/O 동작 : 파일, 디바이스의 동작
      • 파일 시스템 manipulation
      • 통신 : local 혹은 외부 네트워크로의 접근
      • 에러 검출 : HDD Bad Sector 등
    • 시스템 관점
      • 자원 할당 : CPU 사이클, 메모리, 파일 등
      • Logging : 컴퓨터 자원 및 유저 활동의 추적
      • Protection / Security
  • User Interface
    • CLI ( Command Line Interface )
      • 커널 혹은 시스템 프로그램에 의해 동작
      • 보안 문제를 방지하기 위해 Linux/Unix의 경우 Command를 별도 실행 파일로 만들어 두고 shell 자체는 최소한의 기능으로 유지
    • GUI
      • 사용자의 편의 중심
      • 대개 마우스, 모니터, 키보드로 구성
      • 아이콘이 파일, 프로그램 등을 나타냄

System Call

  • 운영체제가 제공하는 일종의 인터페이스

  • 보통 C/C++로 작성되며, Win32, POSIX, JVM 등이 있음

  • System Call 실행

    • 보통 각 System Call에는 번호가 매겨져 있음
    • System Call Interface는 index table로 구성
    • 해당 값에 맞는 번호를 전달하여 system call : 시스템 상태와 정해진 값을 return
  • parameter passing

    • System Call 시 상세 동작 수행
      • ex. file open 시 어떤 파일을 열 것인가?
    • 레지스터를 통한 전달 (Table) : 가장 단순한 방법
      • CPU 레지스터 크기의 한계 존재
    • 메모리 Stack, Queue 사용 : 특정 규약에 따른 parameter passing
    • System Call 시 주소와 Call number를 전달
      • 주소는 parameter가 저장된 주소를 가리킴
      • call number는 해당 system call을 호출
  • system call의 종류

    • 프로세스 생성/삭제
    • 종료, 취소
    • 불러오기, 실행
    • 프로세스 권한 설정
    • 대기, signal event
    • 메모리 할당 및 해제
    • 메모리 오류 시 dump
    • 버그 / 명령 실행 시 디버깅
    • 공유 자원 접근 시 제한
    • 파일 관리
      • 생성, 삭제, 열고 닫기, 읽기, 쓰기, 권한 조정
    • 디바이스 관리
      • 요청, 해제, 읽기, 쓰기, 권한 조정

System Services

  • 운영체제의 기능
    • 파일 관리 - 생성, 삭제, 복사, 이름 바꾸기 등
    • 상태 정보
      • 시간, 디스크 용량, 사용자 수
      • 로깅, 디버깅 등
      • 몇몇 시스템은 레지스트리(설정 정보 저장) 실행
    • 프로그래밍 지원 - 컴파일러, 어셈블러, 디버거 등
    • 프로그램 로드 및 실행- 로더, 링커 등
    • 통신
    • 백그라운드 서비스
      • 서비스, 서브시스템, 데몬(daemon)으로 유명
      • 디스크 점검, 프로세스 스케줄링, 에러 로그 등
      • 부팅 시 동작하나 커널이 아닌 유저 레벨의 프로그램

Linkers and Loaders

  • 작성된 소스 파일은 컴파일되어 Object 파일로 할당(.o)

  • 링커(Linker)는 object 파일을 실행 가능한 파일로 생성

    • 소스 코드(.c, .py), 연관된 라이브러리 등을 연결(Link)
    • 최근 시스템의 경우 실행 파일에 라이브러리를 링크하지 않음
      • DLL(Dynamically Linked Library)
        • 과거에는 모든 프로그램에 라이브러리가 링크되어 메모리 효율이 낮음
        • DLL을 메모리에 로드하여 복수 프로그램이 같은 라이브러리에 접근 가능
        • 이때 라이브러리를 호출할 때만 DLL이 로드됨
  • 로더는 생성된 실행 파일을 메모리에 이동

    • 이 때 pointer 등 할당되는 데이터의 주소 결정
  • 소스 프로그램 >> 컴파일러 >> 오브젝트 파일 >> 링커 (+다른 오브젝트 파일) >> 실행 파일 >> 로더 (+DLL) >> 메모리 할당

Why Applications are Operating System Specific

  • 컴파일된 프로그램은 특정 OS에서만 동작
  • 각 운영체제별로 System Call을 사용하는 방식이 다름
  • 다중 OS를 지원하는 경우
    • 인터프리터 : 파이썬, 루비 등
    • Virtual Machine 내 프로그램 : 자바 등
  • OS specific한 원인 - Application Binary Interface (ABI)
    • 운영체제 별로 API 구조는 동일
    • 함수 실행, 데이터 배치 등의 세부적 구조가 다르기 때문에 OS별로 동작이 다르게 나타남

OS Design and Structure

  • OS design
    • 설계는 목적과 상세 사항의 정의로 시작
      • 사용하는 하드웨어, 시스템 종류 (모바일 등 특정 목적)에 영향
    • 사용자 / 시스템 관점을 볼 필요가 있음
      • 사용자 관점 : 사용 편의성, 이용 난이도, 속도 등
      • 시스템 관점 : 설계 및 구현, 관리 용이성, 오류 신뢰성
    • 설계의 분리
      • 정책 : 어떠한 작업을 할 것인가
      • 동작 : 어떻게 할 것인가
      • 수정이 적은 부분과 많은 부분을 분리
    • OS의 구현
      • 최하단은 assembly (하드웨어 컨트롤)
      • 주요 내용은 C로
      • 시스템 프로그램은 C/Cpp, 스크립트는 최근 쉘이나 파이썬이 이용되기도 함
  • OS Structure
    • Unix (Monolithic Kernel)
      • 커널 내에 모든 기능 포함(I/O handling, filesystem, CPU schedule 등)
      • 빠르지만 복잡함
    • Linux (Monolithic + Modular)
      • 각 시스템 기능을 각각의 메모리 공간으로 할당
    • Layerd approach
      • 운영체제를 기능에 따라 층으로 분리
      • 낮을수록 HW에, 높을수록 유저층에 가까움
      • 자신과 자기보다 하위 층으로만 접근 가능
      • 디버깅이 용이(하위 Layer부터 순차적으로 검증)
      • User Program이 시스템을 이용할 때 Layer를 거쳐야 하는 만큼 Call 회수가 많아지는 단점 존재
    • Microkernel
      • Window, Linux 등의 커널 구조와 반대
      • Mach가 대표적인 예
      • 커널에는 최소한의 기능만 부여하고, 대부분을 유저 기능으로 할당
      • 각 기능 간의 통신은 message passing으로 구현
        • file system, application, driver 등의 user mode로 구현된 기능들의 message passing(MPI)는 kernel을 통해 전달
      • 구현, 디버깅, 관리가 용이
      • 속도가 느림 (User-kernel 간 교환의 overhead)
728x90
728x90
What Operating Systems Do

What Operating Systems Do

  • 컴퓨터 시스템의 구조 : Hardware (CPU, mem, I/O, ...) > Operating System > Application (Compiler, Browser, SDK, ...) > User

  • 사용자 관점에서의 운영체제

    • 간편한 실행, 빠른 속도
    • 모바일 기기의 발전으로 UI의 형태도 다양화 ex. 윈도우(키보드 + 마우스) >> 스마트폰(터치스크린)
    • 사용자 관점이 없는 HW 역시 존재 ex. Embedded System
  • 시스템 관점의 운영체제

    • 시스템과 유저가 1:N 관계
    • 자원 활당 및 관리 역할
    • HW / 유저 프로그램 사이의 조율
  • 운영체제의 정의

    • 좁은 의미 : OS 동작 시 상주하는 프로그램(커널)

Computer System Organization

  • 버스 : CPU, 디스크, 메모리, USB 등의 다수 기기를 연결

  • 컨트롤러 : 컴퓨터 주변 기기를 제어

  • 버퍼 메모리 : 각 컨트롤러의 결과 저장

  • 드라이버 : CPU가 명령을 내릴 때 동작 방식 등을 정의

  • [ CPU - 메모리 - 버퍼 ] 및 [ IO - 버퍼 ]의 과정으로 각각 통신


  • 인터럽트
    • 주변 디바이스들이 CPU에게 이벤트 발생을 알려 주는 것 (ex. HDD의 읽기 완료 신호)
    • Interrupt Service Routine(ISR) : 인터럽트 발생 시 동작해야 하는 명령어
      • 인터럽트 벡터 : ISR이 저장된 주소, 실행하여야 하는 ISR 함수의 메모리 위치를 기록한 Array
    • 인터럽트 발생 시 : > 수행하던 작업 일시 중지 > 인터럽트 처리 > 복귀 후 작업 재실행
    • SW적인 인터럽트도 존재 : Exception(예외)
  • Interrupt handling
    • 인터럽트 발생 시 OS는 작업 중이던 프로그램의 상태를 저장
    • 어떤 인터럽트가 발생했는지 확인할 필요
      • Polling : 디바이스별로 확인, 최근에는 거의 쓰이지 않음
      • Vectored Interrupt System : 각 번호(index)에 해당하는 인터럽트 확인
  • 인터럽트 발생 순서 (I/O Device)
    1. CPU(OS) : driver에게 I/O request 명시
    2. Driver : I/O 컨트롤러에 맞는 명령어 실행
    3. I/O 컨트롤러 : 명령 수행
      • CPU : 다른 작업 수행 및 다른 Event 확인
    4. I/O 컨트롤러 : 작업 완료 후 CPU에게 인터럽트
    5. CPU : I/O 컨트롤러의 인터럽트 index에 맞는 ISR 탐색
    6. CPU : 이전 작업 저장 후 인터럽트 실행
    7. CPU : 인터럽트 처리 완료 후 작업 상태로 복귀

  • I/O Structure
    • System Call : 사용자 프로그램 대신 운영체제가 디바이스 신호를 처리
    • Device-Status Table : 디바이스에 번호를 부여하여 인터럽트 발생 시 어떤 디바이스에서 발생했는지 정확한 판단
  • Storage Structure
    • 메인 메모리 : Random Access, 휘발성 - 휘발되는 데이터를 별도 저장 필요
    • Secondary Storage : HDD, SSD 등 메인 메모리를 보조하여 비휘발성 저장
    • 스토리지 계층
      • 스토리지 별로 가격, 속도, 휘발성이 모두 다름
      • 최상위에 즉시 사용할 데이터 저장
  • Modern Computer (폰 노이만 구조)
    • 캐시 메모리 : CPU 내에서 명령어 로드, 데이터 기록
    • 메인 메모리 : 실제 명령어가 위치
    • DMA(Direct Memory Access)
      • 디바이스에서 데이터 복사 시 CPU의 연산 부담 및 위험성을 경감
      • 디바이스에서 메모리로 데이터를 복사하는 별도 프로세스 할당
      • CPU가 디바이스 데이터 request를 보내면, 디바이스는 DMA를 통해 메모리로 데이터 복사 후 완료 신호만 보내서 CPU의 처리 부담 완화

Multiprocessor

  • 병렬 시스템이라고도 부름
    • 고성능 : 다양한 어플리케이션을 각 프로세스에 할당 가능
    • 신뢰성 : 한 어플리케이션이 동작 실패 시에도 다른 프로세스는 계속 동작
  • 멀티프로세싱의 종류
    • 동기 : 각 프로세서가 한 작업을 분할 처리
    • 비동기 : 각 프로세서가 다른 작업(I/O, 계산 등)
  • 멀티코어
    • 1개 프로세서 안에 다수 Local Cache와 CPU 코어 배치

Operating System Operations

  • 운영체제의 동작
    • Bootstrap
      • 실행 직후 시스템을 초기화
      • 커널을 실행
    • Kernel : 시스템 데몬(daemon) 실행
      • 데몬 : 시스템 소프트웨어 실행 (ex. 새 프로세스 생성)
    • 연결된 디바이스들이 실행되면서 인터럽트 발생
      • CPU에서는 인터럽트를 통해 하드웨어 설정

  • 멀티프로그래밍(Batch System)
    • CPU가 처리할 작업들을 한번에 할당하여 OS가 스케줄링(Scheduling)
    • 고가의 자원을 다수 사용자가 공유하여 사용할 때
  • 시분할(multitasking)
    • Batch System의 경우 다수 프로그램을 하나로 묶어서 처리
    • 시분할의 경우 동작하는 각 프로그램별로 실행 시간을 제한하여 주기적으로 전환
    • 시분할 스케줄링 과정에 시간을 재기 위한 Timer Interrupt 필요
    • 메모리 크기 이상의 프로그램 동작을 위해 가상 메모리 개념 사용
  • Dual Mode (Multimode)
    • 운영체제 동작 시 프로그램들은 서로 영향을 끼치지 않게 해야 함
    • User / Kernel Mode : 운영체제 /사용자가 실행하는지 확인하기 위해 Mode bits가 하드웨어에서 지원
    • Privileged Instructions : 커널 모드에서만 동작하는 특정 명령어
    • User - Kernel Mode 전환
      • User > Kernel : System Call
      • System Call 후 복귀는 인터럽트로 호출

Resource Management

  • Process Management
    • Process : 운영체제가 관리하는 개체
      • Program : Passive Entity / Process : Active Entity
    • Process 동작에 필요한 자원
      • CPU, Mem, I/O, 파일 등
      • Initialize Data
    • 운영체제는 종료된 Process의 자원을 회수
    • 1개 스레드당 1개의 Program Counter(PC)가 할당
      • PC : 처리하는 명령어(Instruction)의 주소를 저장
  • OS의 Process Management
    • 유저 및 시스템 프로세스를 생성 및 삭제
    • 프로세스를 중간에 멈추고 재시작
    • 프로세스 간의 공유 자원 접근 동기화
    • 프로세스 간의 통신 관리
    • 교착(Deadlock) 발생 방지

  • Memory Management(MM)

    • 실행하는 프로그램의 명령어는 메모리에 할당
    • 메모리 사용을 요구하는 프로세스 확인 및 관리
    • 프로세스의 데이터 사용 시점 확인, 필요 없는 데이터는 잠시 공간 확보 후 필요할 때 할당
  • File-System Management

    • 파일 및 폴더의 생성 및 실행, 수정 지원
    • 파일의 소유권 / 그룹에 따라 접근 관리
  • Mass-Storage Management

    • 외부 저장소(HDD, USB 등) 연결 시 마운트/언마운트
    • 속도가 서로 다른 저장소 스케줄링
    • Caching : 자주 사용하는 파일일수록 CPU에 가까운 저장소로 이동

Security / Protection / Virtualization

  • Protection : OS 내의 프로세스 혹은 유저가 시스템 자원에 접근하는 것을 제어

  • Security : 내/외적 공격에 대한 방어 ex. Overflow, 바이러스

    • 유저 구분 : User ID, security ID - 파일 접근 권한 제어
    • Group ID : 해당 그룹에 속하는 유저들의 권한 제어
    • Privilege escalation : 유저가 임시로 상위 권한 접근 - 보안 면에서 많은 고려 필요

  • Virtualization
    • Eumlation
      • 가상머신을 구동하고자 하는 HW가 실제 사용중인 HW와 다를 때 사용
      • 매우 느린 속도
    • Virtualization
      • 가상 OS와 실 환경이 동일한 HW 사용

Computing Environments

  • 기존의 컴퓨팅 환경

    • Standalone 모델
    • 프로그램도 대부분 local 환경
    • 네트워크 환경의 발달로 local device에서 웹의 thin client 역할로 변화
  • 모바일 : 스마트폰, 태블릿 등

    • GPS, 기울기 등의 데이터를 수집 가능
    • Apple IOS / Google Android가 대표적
  • Client-Server 모델

    • 중앙의 서비스 제공자(Server)과 주변의 데스크톱, 스마트폰 등의 단말 장비(Client)로 구분
    • 예 : 데이터베이스, 파일 공유 등
  • Peer-to-Peer 모델

    • 서버/클라이언트 구분 대신 각 클라이언트를 서로 연결, 서로가 서비스 제공자이자 소비자
  • 클라우드 컴퓨팅

    • 컴퓨터에서 사용하던 서비스를 네트워크로 제공
    • ex. AWS, GCP, Azure 등
    • Public Cloud : 유저가 사용 가능한 클라우드 영역 ex. AWS EC2 컴퓨팅 모듈 등
    • SaaS : 인터넷을 통한 어플리케이션 제공
    • PaaS : 어플리케이션을 동작 가능한 환경(플랫폼)을 클라우드에 구축
  • 임베디드 세스템

    • 항상, 실시간으로 동작하는 시스템
    • 특정한 목적으로 한정된 시스템
728x90

+ Recent posts