문제

WAV 파일 목록을 MP3로 인코딩하는 것과 같이 계산 비용이 많이 드는 작업을 수행하는 C # 프로그램이 있다고 가정 해 보겠습니다.보통은 파일을 한 번에 하나씩 인코딩하지만 프로그램이 내가 보유한 CPU 코어 수를 파악하고 각 코어에서 인코딩 스레드를 회전시키기를 원한다고 가정 해 보겠습니다.그래서 제가 쿼드 코어 CPU에서 프로그램을 실행할 때, 프로그램은 그것이 쿼드 코어 CPU라는 것을 알아 내고, 작업 할 코어가 4 개인 지 알아 낸 다음 인코딩을 위해 4 개의 스레드를 생성합니다.CPU.어떻게해야합니까?

코어가 여러 물리적 CPU에 분산되어 있다면 이것이 다를까요?에서처럼 두 개의 쿼드 코어 CPU가있는 컴퓨터가있는 경우 특별한 고려 사항이 있습니까? 아니면 Windows에서 두 다이의 8 개 코어가 동일한 것으로 간주됩니까?

도움이 되었습니까?

해결책

그렇게하지 마세요.

대신 스레드 풀 을 사용하세요.스레드 풀은 새 스레드를 쿼리 할 수있는 프레임 워크의 메커니즘 (실제로는 클래스)입니다.

새 스레드를 요청하면 새 스레드를 제공하거나 스레드가 해제 될 때까지 작업을 대기열에 추가합니다.그런 식으로 프레임 워크는 현재 CPU 수에 의존하지 않고 더 많은 스레드를 생성할지 여부를 결정합니다.

편집 : 또한 이미 언급했듯이 OS는 서로 다른 CPU간에 스레드를 배포하는 역할을합니다.

다른 팁

스레드 풀을 사용하는 것만 큼 간단하지는 않습니다.

기본적으로 스레드 풀은 각 CPU에 여러 스레드를 할당합니다. 작업에 관여하는 모든 스레드에는 비용 (작업 전환 오버 헤드, CPU의 매우 제한된 L1, L2 및 L3 캐시 사용 등)이 있으므로 사용할 최적의 스레드 수는 <=입니다. 사용 가능한 CPU의 수 (각 스레드가 확장 성이 뛰어난 웹 서비스와 같은 다른 시스템에서 서비스를 요청하지 않는 경우) 일부 경우, 특히 CPU 활동보다 더 많은 하드 디스크 읽기 및 쓰기가 필요한 경우에는 실제로 여러 스레드보다 1 개의 스레드를 사용하는 것이 더 나을 수 있습니다.

대부분의 애플리케이션과 WAV 및 MP3 인코딩의 경우 작업자 스레드 수를 사용 가능한 CPU 수로 제한해야합니다. 다음은 CPU 수를 찾는 C # 코드입니다. 라코 디스

안타깝게도 CPU 수에 제한을 두는 것만 큼 간단하지 않습니다. 또한 하드 디스크 컨트롤러 및 디스크의 성능을 고려해야합니다.

최적의 스레드 수를 찾을 수있는 유일한 방법은 시행 착오입니다. 이것은 특히 하드 디스크, 웹 서비스 등을 사용하는 경우에 해당됩니다. 하드 디스크의 경우 쿼드 프로세서 CPU에서 4 개의 프로세서를 모두 사용하지 않는 것이 좋습니다. 반면에 일부 웹 서비스에서는 CPU 당 10 개 또는 100 개 요청을하는 것이 더 나을 수 있습니다.

관리 스레드의 경우이를 수행하는 복잡성이 네이티브 스레드보다 훨씬 더 큽니다. 이는 CLR 스레드가 기본 OS 스레드에 직접 연결되어 있지 않기 때문입니다. 즉, CLR은 관리되는 스레드를 네이티브 스레드에서 적절하다고 판단되는 네이티브 스레드로 전환 할 수 있습니다. Thread.BeginThreadAffinity 함수가 제공됩니다. 네이티브 OS 스레드와 잠금 단계의 관리 스레드. 이 시점에서 네이티브 API를 사용하여 기본 네이티브 스레드 프로세서 선호도를 제공하는 실험을 할 수 있습니다. 모두가 여기에서 제안했듯이 이것은 좋은 생각이 아닙니다. 실제로 스레드가 처리 시간을 더 적게받을 수 있다는 것을 제안하는 문서 가 있습니다. 단일 프로세서 또는 코어로 제한됩니다.

시스템을 탐색 할 수도 있습니다. Diagnostics.Process 클래스. 여기서 프로세스 스레드를 ProcessThread 객체. 이 클래스에는 ProcessorAffinity를 설정하거나 선호 프로세서를 설정하는 메소드가 있습니다. 이것이 무엇인지 확실하지 않습니다.

면책 조항 : CPU 사용률이 낮다고 생각하고이 항목을 많이 조사한 비슷한 문제가 발생했습니다. 그러나 내가 읽은 모든 것을 바탕으로 여기에 게시 된 의견에서도 알 수 있듯이 좋은 생각이 아닌 것으로 나타났습니다. 그러나 여전히 흥미롭고 실험 할 수있는 학습 경험입니다.

여기에있는 대부분의 답변에 동의하지만 새로운 고려 사항 인 Speedstep 기술을 추가 할 가치가 있다고 생각합니다.

다중 코어 시스템에서 CPU 집약적 인 단일 스레드 작업을 실행할 때 Windows Server 2012에서 6 개의 실제 코어 (HT가있는 12 개)가있는 Xeon E5-2430을 실행하면 작업이 12 개 모두에 분산되었습니다. 각 코어의 약 8.33 %를 사용하고 속도 증가를 트리거하지 않습니다. CPU는 1.2GHz로 유지되었습니다.

스레드 어피 니티를 특정 코어에 설정했을 때 해당 코어의 100 %를 사용하여 CPU가 2.5GHz에서 최대가되어 성능이 두 배 이상 증가했습니다.

이것은 내가 사용한 프로그램으로 변수를 증가시키는 루프를 반복합니다. -a와 함께 호출하면 선호도가 코어 1로 설정됩니다. 선호도 부분은 를 기반으로합니다. 이 게시물 . 라코 디스

결과 :

결과

작업 관리자에 표시된대로 CPU-Z가보고하는 것과 유사한 프로세서 속도 :

여기에 이미지 설명 입력

이 작업을 직접 수행하는 것에 대해 걱정할 필요가 없습니다.이중 쿼드 컴퓨터에서 실행되는 다중 스레드 .NET 앱이 있으며 ThreadPool을 통해 또는 수동으로 스레드가 시작되는 방법에 관계없이 모든 코어에 걸쳐 작업이 균일하게 분산되어 있습니다.

프로그램 내부에 루틴을 작성하면 확실히 할 수 있습니다.

그러나 운영 체제가 이러한 항목을 관리하는 데 가장 적합한 후보이므로 시도해서는 안됩니다.사용자 모드 프로그램이 그렇게해서는 안된다는 뜻입니다.

그러나 때로는로드 밸런싱을 달성하고 다른 스레드가 실제로 실행될 것이므로 진정한 멀티 스레드 멀티 코어 문제 (데이터 레이싱 / 캐시 일관성 ...)를 찾기 위해 (정말 고급 사용자의 경우) 수행 할 수 있습니다.다른 프로세서에서.

그렇지만 그래도 달성하고 싶다면 다음과 같은 방법으로 할 수 있습니다.(Windows OS)에 대한 의사 코드를 제공하지만 Linux에서도 쉽게 수행 할 수 있습니다. 라코 디스

위의 루틴이 호출 된 후 스레드는 항상 다음과 같은 방식으로 실행됩니다. 라코 디스

자세한 내용은 설명서 / MSDN을 참조하여 이러한 개념에 대해 자세히 알아보십시오.

각 스레드가가는 곳은 일반적으로 OS 자체에서 처리됩니다. 따라서 4 코어 시스템에서 4 개의 스레드를 생성하면 OS가 각각 실행할 코어를 결정하며 일반적으로 각 코어에서 1 개의 스레드가됩니다.

스레드를 여러 코어로 분할하는 것이 운영 체제의 작업이며 스레드가 많은 CPU 시간을 사용할 때 자동으로 그렇게 할 것입니다.그것에 대해 걱정하지 마십시오.사용자가 보유한 코어 수를 확인하려면 C #의 Environment.ProcessorCount를 사용해보세요.

운영 체제 만이이를 수행 할 수있는 권한이 있으므로이를 수행 할 수 없습니다.당신이 그것을 결정한다면 ..... 그러면 응용 프로그램을 코딩하는 것이 어려울 것입니다.그러면 프로세서 간 통신에도주의해야합니다.중요한 섹션.각 응용 프로그램에 대해 자체 세마포어 또는 뮤텍스를 만들어야합니다 ....... 운영 체제가 자체적으로 수행하여 공통 솔루션을 제공합니다 .......

이런 종류의 항목을 직접 할당하지 말아야하는 이유 중 하나는 특히 NUMA 등을 사용하여 향후 제대로 수행 할 수있는 충분한 정보가 없기 때문입니다.

스레드를 읽을 수 있고 코어가 유휴 상태 인 경우 커널이 스레드를 실행 하므로 걱정하지 마십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top