티스토리 툴바


Dev/C/C++2013/12/13 15:09


몇가지 lock-free 큐 단순 성능 비교


1. 대상 : STL queue with lock, lfds666 library lock-free queue, TBB2.2 concurrent queue, Boost1.55 lock-free queue

2. 방법 : 단순히 int형 숫자 999,999 개를 push 후 3개 스레드에서 동시에 pop 하는 empty 가 될때까지 걸리는 시간 측정

3. 결과 : TBB > Boost > lfds > STL


확실히 lock-free 큐가 성능면에서 뛰어남. CAS, Hazard pointer 와 같은 개념이 적용되는데 결국 원자적(atomic) 단위 명령어 기반으로 구현되어 있는 것 같다. 자세한 건, 공부 필요.







#include "stdafx.h"

#include <Windows.h>

#include <queue>

#include "LockFree.h"

#include "tbb/concurrent_queue.h"

#include "boost/lockfree/queue.hpp"


int count = 999999;



struct StlQ

{

StlQ()

{

InitializeCriticalSection(&m_cs);

}


void push(int i)

{

EnterCriticalSection(&m_cs);

m_q.push(i);

LeaveCriticalSection(&m_cs);

}


int pop()

{

EnterCriticalSection(&m_cs);

if(  m_q.empty())

{

LeaveCriticalSection(&m_cs);

return -1;

}

int v = m_q.front();

m_q.pop();

LeaveCriticalSection(&m_cs);

return v;

}


bool empty()

{

EnterCriticalSection(&m_cs);

bool e = m_q.empty();

LeaveCriticalSection(&m_cs);

return e;

}


std::queue<int> m_q;

CRITICAL_SECTION m_cs;

};


StlQ lockq;

lf_queue q;

tbb::concurrent_bounded_queue<int> tbb_q;

//boost::lockfree::queue<int, boost::lockfree::capacity<count>> boostq(count);

boost::lockfree::queue<int> boostq(count);


DWORD WINAPI STLConsumer(void* p)

{

while (lockq.empty() == false)

{

lockq.pop();

}

return 0;

}


DWORD WINAPI lfdsConsumer(void* p)

{

while (true)

{

int* v = (int*)lf_queue_dequeue(&q);

if (v == NULL)

break;

}

return 0;

}


DWORD WINAPI TBBConsumer(void* p)

{

int v;

while (tbb_q.empty() == false)

{

tbb_q.try_pop(v);

}

return 0;

}


DWORD WINAPI BoostConsumer(void* p)

{

int v;

while (boostq.empty() == false)

{

boostq.pop(v);

//printf("%d \n", v);

//boostq.pop();

}

return 0;

}



int _tmain(int argc, _TCHAR* argv[])

{


DWORD t = 0;

HANDLE thread[3] = {NULL,};



// STL with lock

//////////////////////////////////////////////////////////////////////////

t = GetTickCount();

for (int i = 0; i < count; i++)

{

lockq.push(i);

}


for (int i = 0; i < 3; i++)

{

thread[i] = CreateThread(NULL, 0, STLConsumer, NULL, 0, NULL);

}

WaitForMultipleObjects(3, thread, TRUE, INFINITE);

printf("\n[STL with lock] total elapsed time=%ldms \n", GetTickCount() - t);

for (int i = 0; i < 3; i++)

{

CloseHandle(thread[i]);

}


// lfds666 with lock-free

//////////////////////////////////////////////////////////////////////////

t = GetTickCount();

lf_queue_init(&q);

for (int i = 0; i < count; i++)

{

int* n = new int;

*n = i;

lf_queue_enqueue(&q, n);

}


for (int i = 0; i < 3; i++)

{

thread[i] = CreateThread(NULL, 0, lfdsConsumer, NULL, 0, NULL);

}

WaitForMultipleObjects(3, thread, TRUE, INFINITE);

printf("\n[ldfs with lock-free] total elapsed time=%ldms \n", GetTickCount() - t);

for (int i = 0; i < 3; i++)

{

CloseHandle(thread[i]);

}


// TBB 2.2

//////////////////////////////////////////////////////////////////////////

t = GetTickCount();

for (int i = 0; i < count; i++)

{

tbb_q.push(i);

}


for (int i = 0; i < 3; i++)

{

thread[i] = CreateThread(NULL, 0, TBBConsumer, NULL, 0, NULL);

}

WaitForMultipleObjects(3, thread, TRUE, INFINITE);

printf("\n[TBB with lock-free] total elapsed time=%ldms \n", GetTickCount() - t);

for (int i = 0; i < 3; i++)

{

CloseHandle(thread[i]);

}


// Boost 1.55

//////////////////////////////////////////////////////////////////////////

t = GetTickCount();

for (int i = 0; i < count; i++)

{

boostq.push(i);

}


for (int i = 0; i < 3; i++)

{

thread[i] = CreateThread(NULL, 0, BoostConsumer, NULL, 0, NULL);

}

WaitForMultipleObjects(3, thread, TRUE, INFINITE);

printf("\n[Boost with lock-free (%d)] total elapsed time=%ldms \n", boostq.is_lock_free(), GetTickCount() - t);

for (int i = 0; i < 3; i++)

{

CloseHandle(thread[i]);

}



return 0;

}







'Dev > C/C++' 카테고리의 다른 글

lock-free queue 단순 성능 비교  (0) 2013/12/13
development of 64-bit C/C++ applications  (0) 2011/12/12
RCF - Interprocess Communication for C++  (0) 2010/02/17
Optimize in C++  (0) 2009/11/27
C++ 개발자를 위한 병렬 프로그래밍  (0) 2009/09/22
openMP in VC9  (2) 2009/04/28
Posted by 유근호

TRACKBACK http://microdev.tistory.com/trackback/170 관련글 쓰기

댓글을 달아 주세요

Dev/Go2012/08/22 23:43

Go 언어를 공부하면서 만들어 본 간단한 MPEG-2 TS 포맷 확인 프로그램.

TS 파일 경로는 hard coding --;;


느낀건데 easy! rapid! fast coding! 

비즈니스 로직 중, customize 가 필요한 부분에 빠른 코딩으로 적절하게 대응할 수 잇을 것 같다.


package main

 

import (

//"io"

"os"

//"strconv"

"fmt"

)

 

 

func main() {

fd, err := os.Open("d:\\양화진 밴드_It's Alright_0.ts")

if err != nil {

panic(err)

}

test_count := 5

buf := make([]byte, 188*test_count)

n, err := fd.Read(buf)

if n == 0 {

panic(err)

}

i := 0

var syncword_lit byte = 0x47

for {

if (i == test_count) {

break;

}

fmt.Printf("%#x ", buf[i*188])

syncword := buf[i*188];

if syncword != syncword_lit {

print("\nno MPEG-2 TS syncword 0x47");

return

}

i++

}

print("\nIt's MPEG-2 TS format")

fd.Close()

}

'Dev > Go' 카테고리의 다른 글

공부 - mpeg-2 ts 포맷 확인 샘플  (0) 2012/08/22
Posted by 유근호
TAG 0x47, go, MPEG-2, TS

TRACKBACK http://microdev.tistory.com/trackback/169 관련글 쓰기

댓글을 달아 주세요