Designing & Optimizing Software for N Cores을 보다 보니까, 더블 버퍼링을 이용해서 스레드 동기화를 줄이는 것이 소개돼 있었습니다. 더블 버퍼링의 개념은 그래픽스 프로그래머에겐 익숙한 개념인데, 이걸 스레드 동기화에도 사용할 수 있다는 게 신선하게 느껴졌습니다. 그 문서엔 구현이 구체적으로 나와 있지 않았는데, 어떻게 구현하면 될 것인지 그냥 제 나름대로 생각해 보았습니다.

더블 버퍼링엔 두 개의 버퍼가 필요합니다. 하나는 읽기용이고, 다른 하나는 쓰기용입니다. 외부로부터 요청을 받아 어떤 일을 하는 예제를 만들어 보겠습니다.
class work_type
{
};
class worker_type
{
public:
worker_type()
:
my_current_work(&my_work[0]),
my_next_work(&my_work[1])
{
}
void add_work(const work_type& work)
{
my_next_work->push(work);
}
protected:
typedef std::queue<work_type> work_queue_type;
void do_work()
{
for (work_queue_type::iterator work_iterator = my_current_work->begin(); work_iterator != my_current_work->end(); ++work_iterator)
{
// 각 작업을 합니다.
}
my_current_work.clear();
std::swap(my_current_work, my_next_work);
}
work_queue_type my_work[2];
work_queue_type* my_current_work;
work_queue_type* my_next_work;
};
대략 위와 같은 형태가 될 것 같습니다. 외부에선 항상 add_work로 다음 버퍼에만 접근해서 작업을 추가하므로, 이 객체가 do_work로 현재 버퍼를 이용해 자신의 일을 처리하고 있는 데엔 영향을 주지 않습니다. 따라서 위와 같이 하면, 큐에 작업을 추가할 때마다 크리티컬 섹션 등으로 스레드 동기화하던 부하를 없앨 수 있습니다. 그런데 참고로, 버퍼 교환엔 동기화가 필요할 수도 있습니다.
2009/10/11 11:19 2009/10/11 11:19

트랙백 주소 :: http://www.easyisright.net/trackback/609

댓글을 달아 주세요

  1. 강성희 2009/10/11 20:28  댓글주소  수정/삭제  댓글쓰기

    bool 변수를 스위치해 주면서 동일한 값 두 개를 번갈아 가면서 사용하는 방법도 있는 걸로 알고있습니다.

    이 경우 bool값은 Interlock계열 락으로 동기화 시킬 수 있으니 동기화 시 드는 부하량을 줄일 수 있는 걸로...ㅎㅎ