Barriers and Condition Variables

강병우·2023년 10월 30일
0

병렬프로그래밍

목록 보기
15/24
post-thumbnail

Barrier

모든 스레드가 같은 지점에서 실행될 수 있도록 보장해주는 것을 Barrier이라고 한다. 특정 지점을 barrier로 막아두고, 모든 스레드가 도착할 때까지 대기한다고 보면 된다. 일반적으로 Barrier를 많이 쓰게 되면 성능이 좋진 않다.

기다리는 지점은 모두 똑같지만, 각 스레드별 실행시간, elapsed의 값은 모두 다를 것이다. 그렇기 때문에, 가장 오래 걸린 스레드의 elapsed를 계산하여 모든 스레드가 barrier에 도착하는데 걸린 시간을 구할 수 있다.

Barrier를 통해 디버깅도 할 수 있다.

모든 스레드가 여기까지 도착했다는 의미이다. 도착하지 못했다면, printf이 실행되지 않을 것이다. 이걸로 디버깅을 할 수 있다.

어떻게 구현할까?

Busy-Waiting이나 Mutex로 쉽게 구현할 수 있다. 예시 중 하나로, mutex에게 보호받는 공유 카운터변수를 사용하면 된다. 각 스레드들이 critical section에 진입할 때마다 카운터 변수의 값을 증가시킨다.

Mutex를 이용한 구현

while에서, 공유 카운터의 값이 스레드 개수보다 낮을 경우 계속 기다린다. 모든 스레드가 통과하면 스레드 개수와 같아지므로, while에서 탈출할 것이다. -> 이것이 Barrier의 역할이다.

세마포어를 이용한 구현

  1. / Barrier / 구문까지 모든 스레드가 동일하게 도착할 것이다. 그 다음이 중요하다. count_sem을 소비하여 한 스레드가 critical section에 진입할 것이다.

  2. if(count == thread_count - 1)은 통과한 스레드의 개수가 스레드의 총 개수인지 질의하는 것이기 때문에 이를 넘기고 else로 진입한다.

  3. 카운터를 증가(=스레드가 통과했음)시키고 count_sem을 반납한다. 그리고 barrier_sem을 소비하여 기다린다.

  4. 마지막 스레드가 통과했을 때, if문을 통과하여 count_sem을 반납하고 스레드의 개수만큼 barrier_sem을 반납한다.

  5. barrier_sem의 세마포어값은 다시 1로 되어 sem_wait(&barrier_sem)에서 벗어나게 된다.

Condition Variables

어떤 이벤트나 조건을 만족할 때까지 스레드를 정지시키는 것을 Condtion Variables라고 한다. 어떤 이벤트가 발생했을 때, "Wake Up" 신호를 보내 스레드를 다시 실행시킨다. 항상 Mutex와 연관되어있다.

pthread에서의 Condtion Variables는 pthread_cond_t 타입이다.

int pthread_cond_signal(pthread_cond_t* cond_var_p /* in/out */); : 하나의 스레드에 대해 Unlock 신호를 보낸다.

int pthread_cond_broadcast(pthread_cond_t* cond_var_p /* in/out */); : 모든 스레드에 대해 Unlock 신호를 보낸다.

다른 스레드 콜에 의해 Unblocked 될 때까지 스레드 실행이 멈춰지게 된다.

위 소스코드처럼, 조건이 안 맞으면 wait을 해주고 조건을 만족하게 될 때 broadcast하여 모든 스레드들을 깨워줄 수 있다. 그 후 mutex를 unlock해주면 된다.

0개의 댓글