2011-01-19 3 views
1

내 코드에 2/4 스레드가 몬테카를로 시뮬레이션을 수행했습니다. 각각은 수많은 실험을 실행하고 모두 결과를 stl 벡터로 수집합니다. 제 질문은 이것입니다 : 각 스레드가 1000 개의 실험을 순차적으로 실행한다고 가정 해보십시오. 그 결과를 공유 벡터 하나에 저장하는 것이 더 낫지 않습니까? 그들이 일정한 양의 데이터를 얻을 때까지 기다리면 벡터에 쓰기가 더 오래 걸릴 것이므로 두 번째 솔루션이 반드시 첫 번째 솔루션보다 반드시 좋은 것인지 확실하지 않습니다.C++ 멀티 스레드 최적화

추신 : 각 실험은 수치 계산이므로 IO 작업이 없습니다.

감사

+2

공유 잠금이없는 스택을 사용하여 결과를 누를 수 있습니다. – GManNickG

답변

8

모든 결과가 계산 될 때까지 당신이 벡터의 요소 중 하나 개 범위에 벡터에서 4,000 결과에 대한 결과의, 공간을 미리 할당을 사용하고 각 스레드 쓰기를하기 전에 대기려고하는 경우 . 두 스레드가 벡터의 동일한 요소에 액세스하지 않으므로 잠금이 필요하지 않습니다.

계산 결과를 사용하려면 벡터 대신 일종의 동시 대기열 데이터 구조를 사용하십시오.

2

벡터에서 2000-4000 개 요소 만 넣으면 나는 어느 방향으로나 많은 차이를 만들지는 모르겠다.

알고리즘에 가장 자연스러운 작업을 수행하십시오. 그게 잘 작동하지 않으면 다른 방법으로 그것을 잘보세요.

조금 생각한 후에는 각 스레드가 결과를 로컬 벡터에 저장하고 로컬 벡터의 내용을 '글로벌'벡터로 복사 할 수있는 두 가지 목적 (단순성 및 속도)을 제공 할 수 있습니다 잠금). 물론, 업데이트를 얻기 전에 스레드가 완전히 끝날 때까지 결과를 기다릴 수있는 한 기다리는 것이 좋습니다.

0

단일 연결 목록은 벡터보다 더 나은 선택 일 수 있습니다.

오직 하나의 쓰레드 읽기와 하나의 쓰레드가 FIFO에 쓰여 있다면 .. 동기화가 필요 없습니다. 트릭은 적어도 하나의 '더미'요소를 항상 목록에 유지하는 것이며 head == tail 인 경우 fifo는 비어 있습니다. 헤드 및 테일 포인터는 푸시 및 팝용으로 조작 할 수 있으므로 동기화 할 필요가 없습니다.

이것을 사용하면 몇 가지 Q를 만들 수 있습니다. 동기화가 필요하지 않습니다. 새 항목/삭제 항목은 다음과 같습니다. 시간이 걸릴 ... 당신은 재사용 가능한 요소를 보유 Q를 가질 수 있습니다.

행운을 빈다.

기억하십시오. 정확히 한 명의 독자와 정확히 한 명의 작가 ... 더 이상은 없습니다. 트릭은 이것처럼 Q가 많아서 객체를 재활용하는 Q도 많고 ... 스레드 동기화 작업이 필요하지 않습니다.

Q가 비어있을 경우 .. sleep()/wakeup() 기능이 필요합니다.

그리고 이미 내가 말한 적이없는 경우를 대비해서 .. 정확히 한 명의 독자와 정확히 한 명의 작가.

+0

포인터에 대한 액세스는 여전히 잠금 또는 원자를 사용하여 동기화해야합니다.연결된 목록은 실적을 소멸시킬 수 있습니다. 링크 된 목록은 다른 시퀀스 컨테이너와 비교하여 대단히 비효율적 인 대부분의 사용 사례를위한 것입니다 (성능 비용이 많은지 여부는 OP의 사용 사례에 전적으로 달려 있습니다.) –

+0

@James .. 아니요 .. 포인터에 대한 액세스가 동기화되지 않아도됩니다. 그것은 아름다움입니다. 개념적으로 생각해보십시오. 긴 단일 링크드리스트가 있다면 .. 두 스레드가 동일한 메모리 위치를 변경하게됩니다! – vrdhn

+0

한 스레드 만 포인터를 수정하고 다른 스레드가 스레드를 읽는 중이더라도이 스레드에 대한 액세스는 동기화되어야합니다. 이것은 항상 가능하며 연결된 목록을 대기열로 사용하는 경우 머리 및 꼬리 노드에서 발생할 확률이 높습니다. –