rein's world

Spin buffer explained : Part 2

전번에 들고 나왔었던 스핀 버퍼 (spin buffer) 에 대한 설명. 스핀 버퍼 정의대로 3개의 동일한 버퍼 배열들을 가지고 진행하게 되며, 앞에서 설명한 busy 여부는 Free 상태만 non-busy로 생각하면 된다. 그리고 빗금친 버퍼는 데이터가 들어있는 것이다.

생산자-소비자 모델 (consumer-producer model)에서, 생산자가 1 개의 아이템을 버퍼에 집어 넣은 형태가 다음이라고 하자. (다음 다이어그램부턴 여기에 대한 연속)

spin buffer example 01

생산자가 버퍼 1개를 쓰고 나면 다음 스핀 버퍼(여기선 다음 줄 정도로 생각하면 된다) 가 Free 상태이므로 거기로 옮겨가게 되고, 읽을게 없는 소비자도 2번째 줄로 옮겨오게 된다. (이에 따라 첫번째 줄은 Free상태로) (중간 줄이 복잡한데 생산자가 빠져나가고 바로 소비자가 들어와서 그렇다)

spin buffer example 02

위 다이어그램의 상황에서 소비자가 좀 오래 걸리는 연산을 하느라 빗금친 버퍼를 처리하는데 좀 오래 걸린다고 생각해보자. (사실 소비자는 언제나 생산자보다 빨라야한다 ) 생산자는 세번째 줄에 버퍼를 하나 쓰고 바로 첫번째 줄로 넘어가게 된다 (첫번째 줄이 Free 상태이므로). 그리고 소비자가 두번째 줄을 점유하는 동안에는 첫번째 줄에 계속해서 쓰게 된다.

spin buffer example 03

…이제 좀 여러 단계를 건너 뛰어보자. 소비자가 2번 째 줄을 처리하고 (그에 따라 생산자가 2번째 줄로 쫓아오고), 3번째 줄을 처리하고 그리고 결국엔 첫번째 줄을 처리하기 시작한다. 그러면 생산자는 이를 계속 쫓아서읽고있는 버퍼의 바로 직전 버퍼들에 열심히 쓴다. 그 상태를 그려보면 아래와 같다.

spin buffer example 04

이에 따라 읽기/쓰기 연산이 일어나는 버퍼 배열이 절대로 겹치지 않기 때문에 – 소비자는 생산자가 나가야 들어가서 읽고, 생산자는 소비자가 없는 곳에만 쓴다 – lock-free 하게 동작하는 생산자-소비자 모델이 된다.

물론 이런 경우에도 아예 아무 아이템도 없거나 / 버퍼가 꽉차거나 하는 경우엔 대기 하기 위한 동기화 객체가 필요하긴 하다. 그래도 생산자 소비자가 하나의 lock을 놓고 경쟁하는 일은 절대 일어나지 않기 때문에 양자의 독립적인 동작이 거의 보장된다.