![]() by roadster 카테고리
전체잡설 개발 - STL 개발 - 일반 개발 - 디자인 미분류 이전블로그
more...이글루링크
미친병아리의 이글루스~★~ 우하하!!~ 프로.. 최근 등록된 덧글
VS2015부터 안되는거 같은..by 음... at 07/11 오..잘 배워갑니다. .. by 안녕하세요 at 11/25 setlocale(LC_ALL, .. by 최익필 at 09/28 setlocale(LC_ALL, .. by 짐퀴 at 07/07 전 오히려 느린것 보단 .. by 김양희 at 07/21 위에서 cout.imbue(l.. by 상한레몬 at 03/03 문제는 std::cout.imb.. by 냐모 at 10/31 삽질할 뻔 했던 시간 절약.. by 이규원 at 07/10 어익후 감사합니다. 전 .. by 한손에자유 at 06/02 감사합니다.^^ 저두 .. by shady at 01/27 |
멀티쓰레드 IO를 하다보면 N개의 쓰레드에서 IO작업을 하고 하나의 로직쓰레드에서 IO가 끝난 데이터를 처리하는 작업을 하는 경우가 있다. (대표적인 방식이 IOCP) (여러개의 IO쓰레드와 하나의 로직쓰레드를 사용하는 이유를 알고 싶으면 아래의 참고를 참고...) 보통 이런 방식을 사용할 때 동기화를 하기 위해서 사용하는 방식은 내가 써본 바로는 크게 두가지가 있었다. l 실시간 동기화 n 큐에서 원소를 빼낼 때 마다 락을 걸어서 동기화하는 방법. n 매우 비효율적이나 코드가 간단하고 데이터 복사에 대한 오버헤드가 없다. l 복사 동기화 n 한번 락을 걸고 데이터를 다 빼내와서 새로운 큐에 복사를 하고 락을 푼 후 새로운 큐에 대해 반복적으로 작업을 처리. n 락에 대해서는 효율적이지만 데이터 복사가 일어나고 복사하는 동안 장시간 락이 걸리는 단점 이 두 가지를 장점만을 결합하고 싶어서 이렇게 만들어보았다. ![]() 기본적인 원리는 락 한번 걸 때 여러 개의 데이터를 얻어오는 대신 데이터 복사를 없애고 싶었다. 원리는 간단하다. 우선 큰 큐 객체 안에 두 개의 작은 큐가 있다. 두 개는 동일한 큐로 IO작업 결과를 담을 수 있다. 그리고 IO쓰레드들과 로직쓰레드는 직접 큐 객체에 접근하는 것이 아니고 각각의 큐를 가리키는 두 개의 포인터에 접근을 한다. swap을 요청하게 되면 데이터를 복사하지 않고 포인터만 교환한다. 포인터 교환하는데 드는 비용이 엄청나게 작기 때문에 락 걸리는 시간도 매우 작다.
아쉬운 점은 다수의 쓰레드가 데이터를 입력할 때 매번 락이 걸리기 때문에 좀 아쉽긴 하다. 이 부분은 다른 방식으로 해결해야지…
IO 쓰레드가 여러 개인 이유는 아시다시피 자원요청에 대한 대기 시간 동안 효율적으로 CPU를 사용하고, 자원에 접근하는 코드가 간결해진다. (쓰레드 내에서 블락이 걸려도 상관없기 때문에) 로직쓰레드가 하나인 이유는 로직 처리가 사이클이 작고 반복횟수가 많은 경우여서 여러 개를 사용했더니 내부적으로 동기화가 필요해지고 동기화로 인한 비효율적인 락이 생겨서 더 느려지는 현상이 발생하였다. 그래서 차라리 하나를 빨리 돌리는게 더 효율적이라고 판단, 모든 락을 제거하고 하나의 쓰레드로 변경하였다.
| ||||