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로 현재 버퍼를 이용해 자신의 일을 처리하고 있는 데엔 영향을 주지 않습니다. 따라서 위와 같이 하면, 큐에 작업을 추가할 때마다 크리티컬 섹션 등으로 스레드 동기화하던 부하를 없앨 수 있습니다. 그런데 참고로, 버퍼 교환엔 동기화가 필요할 수도 있습니다.

댓글을 달아 주세요
bool 변수를 스위치해 주면서 동일한 값 두 개를 번갈아 가면서 사용하는 방법도 있는 걸로 알고있습니다.
이 경우 bool값은 Interlock계열 락으로 동기화 시킬 수 있으니 동기화 시 드는 부하량을 줄일 수 있는 걸로...ㅎㅎ
그 방법은 잘 모르겠네요. 구체적인 구현을 보아야 알겠습니다.