2009-11-24 3 views
1

지금 막 mutithreaded 프로그램을 작성하는 법을 배우고 있으며, 프로그램에 얼마나 많은 스레드가 최적인지에 대한 가상의 질문이 있습니다.몇 개의 스레드를 만들까요?

두 가지 시나리오를 설명해 드리겠습니다.

첫 번째 시나리오는 내가 쉽게 멀티 스레드이지만 각 스레드는 많은 작업을 수행 할 것입니다 (각 스레드의 실행 시간은 초 단위 임).

두 번째 시나리오는 내가 쉽게 멀티 스레드이지만 각 스레드는 매우 짧은 실행 시간 (밀리 초 단위)을 가지고 있다는 것입니다.

이러한 시나리오 중 하나에서 프로그램을 mutithreading하는 가장 효율적인 방법은 무엇입니까? 시스템 메모리가 허용하는만큼의 스레드를 생성하는지 또는 새 스레드를 생성하기 전에 스레드가 완료 될 때까지 대기하므로 한 번에 최대 4 개의 작업자 스레드 만 실행됩니다.

한편, 많은 스레드는 스레드 간 코어 전환에 오버 헤드 문제가있을 수 있습니다. 반면에 실행중인 스레드의 수를 제한하면 추가 검사 조건을 실행하고 카운터 변수를 잠그고 잠금을 해제하여 실행중인 스레드 수를 추적하고 이전 스레드가 완료되면 새 스레드를 생성합니다. .

많은 작은 스레드가있는 경우 스레드가 실행되기 전에 너무 많은 스레드 전환이 발생하지 않으므로 가능한 많은 스레드로 시스템을 오버로드하는 것이 가장 좋습니다. 그것은 스레드의 수를 지속적으로 추적하는 오버 헤드를 줄일 수 있습니다.

또한 큰 스레드가 몇 개 밖에없는 경우 (몇 개는 몇 백 개 정도됩니다), 스레드를 추적하여 스레드가 최적의 수로 유지되도록하는 것이 좋습니다. (쓰레드가 끝나기 전에 여러 번 전환하기 때문에 오버 헤드가 더 커질 것이기 때문에) 아주 많은 쓰레드 스위칭이있다.

이러한 가정은 각각의 경우에 대해 정확합니까? 아니면 모든 상황에서 올바른 일을하는 보편적 인 방법이 있습니까?

참고 : 이것은 muti 코어 시스템 (지금은 하이퍼 스레딩을 무시할 수 있음)을 가정하고 mutithreading과 관련된 일반적인 문제를 무시하도록합니다 (모든 스레드가 개인 쓰기 위치를 갖고 있으며 공용 쓰기 위치 만 읽을 수 있다고 가정, 잠금 잠금 해제는 활성 스레드 수에 대해 카운터를 증가 시키거나 감소시킬 때만 발생합니다).

감사합니다, 이것에

-Faken

답변

5

시나리오 # 1 : CPU 코어의 수

시나리오 # 2 여기서 'N', N 스레드를 확인 : 같은, 대신 생성하고 스레드에게 모든 시간을 죽이는, 작업 항목/스레드를 사용 .NET Parallel Framework처럼 풀 기반 접근 방식.

편집 : 이것은 # 2 커버하는 좋은 기사입니다 - http://msdn.microsoft.com/en-us/magazine/cc163340.aspx을; PFx가 실행할 스레드 수를 파악하게되면 작업이 서로 어떻게 관련되어 있는지 설명하게됩니다.

+0

좋은 지적. 작업이 마이크로 초 동안 실행되면 스레드를 설정하고 실제 작업을 수행하는 데 거의 오랜 시간이 걸립니다! –

+0

또한 C++ 및 Visual Studio 2010을 사용하는 경우 Parallel Pattern Library 및 Concurrency Runtime을 사용할 수 있습니다 (PFX는 .NET 임). .NET 및 C++ 코드에 대한 포인터는 동시성 센터를 참조하십시오. http://msdn.microsoft.com/en-us/concurrency/default.aspx – Rick

2

일반적인 방법은 스레드가 구성 계산하게하고, 여러 구성에서 응용 프로그램 성능을 프로파일 링하는 것입니다.

대부분의 경우 스레드 또는 컨텍스트 전환과 관련된 오버 헤드가 아니라 공유 리소스에 대한 액세스를 동기화하여 발생하는 병목 현상으로 인해 멀티 스레드 응용 프로그램의 비 효율성이 발생합니다. 코드가 교착 상태라고 가정하더라도 많은 IO가 발생하면 동기화 구현이 제대로 이루어지지 않으면 병렬화로 인해 얻게 될 이점을 효과적으로 없앨 수 있습니다.

+0

각 스레드가 글로벌 정보를 읽고 나서 하드 드라이브로 바로 뱉어 버리면 어떨까요? 내 병목 목은 하드 드라이브 쓰기 순서가 맞을거야? 이 경우 많은 스레드가 쓰기 시퀀스를 요청하면 (각 파일은 최대 몇 KB 만), HD는 계속 진행하기 전에 파일을 쓰거나 하나의 파일을 끝내겠습니까? – Faken

+0

드라이브에 따라 다릅니다.대부분의 하드 디스크 드라이버 (원래는 SCSI만이었지만 지금은 ATA도 있음)는 스 캐터 - 수집 작업을 지원합니다. 여기서 요청 그룹은 드라이브 헤드의 움직임에 맞게 내부적으로 다시 시퀀싱됩니다. – devstuff

+0

또한 OS 성능 카운터를 사용하여 조기 최적화를 수행하기 전에 병목 현상이 실제로 발생한 위치를 확인하십시오. – devstuff

0

충분한 숫자로 시작한 다음 좋은 성능을 얻기 위해 실행할 스레드의 정확한 수를 알아 내기 위해 통계를 수집합니다.

+0

실행중인 PC에 따라 다릅니다. – mpen

+0

물론 환경, 작업 스레드의 종류는 모든 문제를 다할 것입니다 –

2

이되지는 하드 및 빠른 응답과 함께 질문하고, 몇 점을 생각 : 당신의 스레드가 매우 짧은 살고있다

때문에, 어쩌면 당신이 그들을 관리하는 풀을 사용하는 방법에 대해 생각해야 하는가? 호스트 시스템 및 작업 프로파일 (각 코어에 대해 시작하는 말)에 적합한 스레드 수를 가진 풀을 생성하고 피드를 일종의 대기열에서 수행하도록 할 수 있습니다. 이렇게하면 새 스레드를 시작하는 오버 헤드를 없애고 각 태스크마다 스택을 할당 할 수 있습니다.

풀의 적절한 스레드 수는 실행중인 작업의 유형에 따라 다릅니다. CPU 바운드 작업 인 경우 CPU 당 하나의 스레드가 적합합니다. 필요하지 않을 때 컨텍스트 전환을 피할 수 있습니다. 다른 한편으로 소켓 통신을하는 쓰래드와 같은 IO 바운드 작업이라면 IO 번호 입력을 기다리는 동안 프로세서를 더 잘 활용할 수 있도록 그 숫자를 두 배로 늘릴 수 있습니다.

어쨌든 간단히 말해서 이런 종류의 일에 맞는 방법은 없습니다. 어느 때보 다 비효율적 인 부분을 파악하고 결과에 따라 코드를 조정하십시오.

1

Windows 프로그램을 의미한다고 가정하면 닷 닷넷 프로그램이 아니라 C++ 인 경우라도 시작하기 전에 조 더피 (Joe Duffy)의 "동시 프로그래밍"을 피해야합니다. 그는 Windows에서 제공하는 스레드 풀링 루틴을 사용하기에 좋은 음모를 꾸미는데, 이는 이미 프로세서 구성을 내부에서 조정하여 어깨에서 부담을 덜어주기 때문에 가장 확실합니다.
그럼 어쨌든 자신 만의 롤업을한다면, 책 전체에 걸쳐 논의 된 잡동사니는 분명히 표준 함정에 걸려 넘어지는 것을 막을 수 있습니다.

0

스레드가 싸지 않습니다. 나는 그들을 사용하는 기본적으로 두 가지 이유를 알고 :

  1. 병렬로 작업 하드웨어의 여러 조각을 얻기 위해, 그들은의 다른 측면에 CPU 코어, 디스크 헤드, 기계의 다른 종류, 또는 서버 수 있는지 여부 세계.

  2. 자신의 세션이있는 사용자와 같이 여러 사람이 동시에 작업 할 수 있습니다. 여기서 장점은 속도가 아니라 각 사용자의 상호 작용 순서를 쉽게 코딩 할 수 있다는 것입니다.

또는 둘 다 크랭크 할 스레드가 있고 둘 중 하나가 사용자에게 응답하는 경우입니다.

관련 문제