어제의 나보다 성장한 오늘의 나

[OS] 동기화 하드웨어 (Synchronization Hardware) 본문

Operating System

[OS] 동기화 하드웨어 (Synchronization Hardware)

today_me 2022. 5. 29. 01:39
반응형

 

 

 

Hardware support를 기반으로 한 Synchronization Problem을 해결법에 대해 알아보자

 

 

1) 싱글 코어 프로세서

 

인터럽트를 사용할 수 없게 끔 싱글 코어 프로세서를 사용하는 것이다.

그러면 Synchronization이 발생하지 않는다.

멀티 프로세스 시스템에서는 이 방식이 매우 비효율적이다.

확장되어 있는 OS들 에서는 이 방식을 채택하지 않는다.

 

2) Hardware Support 세 가지

 

Memory barriers

Hardware instructions

Atomic variables

 

 

Memory barriers

 

오퍼레이션들의 순서를 보장해주는 장치

보통 store 오퍼레이션들 전후로 위치 한다

 

memory_Barrier를 설치함으로써 reorder방지

◎ very low - level operation -> kernel 개발자들에 의해 사용됨  (일반 프로그래머들이 사용하기는 어렵고 복잡하다.)

 

 

 

사용 방식 Code

 

// Thread 1

while(!flag)
	memory_barrier();
print x;
// Thread 2

x = 100;
memory_barrier();
flag = true;

 

 

 

Peterson's Solution 에서의 활용 

 

While (true) {
	Flag[i] = true; 
    memory_barrier();      // reorder 방지
	turn = j; 
	while(flag[j] && turn == j);

.
.
.

 

 

② Hardware Instruction

 

변수들을 이용하여 Synchronization을 해결하는 두 가지 instructions

 

 

- 1) Test - and - Set

 

 

사용 방식 Code

boolean test_and_set(boolean *target){

	boolean rv = *target;
	*target = true;
    
    return rv;
}

 

target을 rv에 담아 반환

target을 ture로 변경

 

 

 

응용

do{
    while(test_and_set(&lock));
    
	/* critical section */
    
    lock = false;
    
    /* remainder section */

}while(true);

 

▷ Lock == true

test_and_set == true   ->   while 속에 갇힘   ->   다른 thread가 cs 안에 있는것    ->    lock = false 될 때 까지 기다림.

 

 

▶ Lock == false

test_and_set == false   ->   while 조건 false   -> cs 진입   ->   cs 탈출 후 lock = false

 

 

이를 통해 Atomic 하게 실행 된다.

 

 

※ cs 는 critical section

atomic 은 실행중일 때 누구도 interrupt 할 수 없는 것을 말한다.

 

 

 

② - 2) Compare - and - Swap

 

 

사용 방식 Code

 

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

 

 

 

응용

 

while(true){
	while(compare_and_swap(&lock , 0 , 1) != 0);
    
    /* critical section */
    
    lock = 0;
    
    /* remainder section */

}

 

 

▷ Lock == 0

compare_and_swap == 0   ->   while 조건 false  ,  lock == 1   ->   CS 진입

 

 

▶ Lock == 1

compare_and_swap == 1   ->   while 조건 true   ,   lock == 1   ->   wait

 

 

Atomic하게 진행됨

 

 

 

만약 Process 가 3개 라면??

 

p1 cs 진입  ->   p1 cs 탈출  ->   p2 cs 진입  ->   p2 cs 탈출  ->   p3 cs 진입   ->   p3 cs 탈출

이 과정이 순조롭게 진행 될까??

 

그렇지 않다.

 

왜냐하면 p1 이 cs 탈출한 뒤 p2가 selected 될 것이라고 보장할 수 없기 때문이다

그러므로  bounded-waiting requirement를 충족 시키지 못한다.

 

이것을 보완한 compare - and - swap을 알아보자

boolean waiting[n];
int lock;
while (true) {
	waiting[i] = true;
    ket = 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 */


}

 

◎ waiting[n] 이 추가됨

◎ thread_i는 Lock == 0 일 때   +   waiting[i] == ture   +   thread_i-1이 cs를 나왔을 때 진입 가능

 

 

 

 

 

 

③ Atomic variable

 

Data types(Int , Boolean) 에게 Atomic update를 준다.

 

 

 

Compare - and - Swap 같은 instruction들이 사용 된다.

 

 

Example :  increment()

void increment(atomic_int *v)
{
	int temp;
    
    do {
    	temp = *v;
    }while(temp != compare_and_swap( v, temp , temp+1 ))

}

 

compare_and_swap을 사용

increment를 진행하는 동안 atomic하게 진행되도록 함

 

 

 

이렇게 세 가지의 hardware 기반의 support 세 가지를 알아보았다.

 

위에서 봤듯이 hardware support로도 synchronization을 해결할 수 있다.

그러나 low-level인 기계어로 작성되어 있기 때문에 프로그래머들이 사용하기에는 어렵다고 알려져 있다.

 

이를 대체하여 software 기반의 synchronization tool들 ( mutex , semaphor , monitor 등 )을 사용하기도 한다.

반응형
Comments