2012-12-12 4 views
25

시나리오 CPU 코어의 : 나는 샘플 응용 프로그램이 있고 나는 3 가지 시스템 구성이 -아니오에 기반한 스레드 구성.

- 2 core processor, 2 GB RAM, 60 GB HHD, 
- 4 core processor, 4 GB RAM, 80 GB HHD, 
- 8 core processor, 8 GB RAM, 120 GB HHD 

효과적으로 내 응용 프로그램에 대한 H/W 기능을 이용하기 위해서는를, 나는 더 구성 할. 응용 프로그램 수준의 스레드 수 그러나 시스템 기능을 철저히 이해 한 후에 만이 작업을 수행하려고합니다.

max와 min을 참조하여 시스템의 우수성을 판단 할 수있는 방법 (system/modus/tool)이있을 수 있습니까? 효율과 성능을 저하시키지 않으면 서 최적의 서비스를 제공 할 수있는 스레드가 &입니다. 이것으로 전체 애플리케이션 정의를 수행하고 각 하드웨어 구성에 대해 최상의 성능을 얻을 수있는 애플리케이션의 값만 구성 할 수있었습니다.

편집 됨 1 : 특정 h/w 구성에 대한 기준을 설정하는 방법에 대해 읽어 보시기 바랍니다.

Edited2 : 이 더 직접 만들려면 -/배우 나 일반/전체적인 수준에서 스레드의 CPU 관리에 대한 약간의 이해를 얻기 위해 읽을 수있는 자원/쓰기 업에 대해 알고 싶습니다.

+0

최소 수에 대한 최적 값을 찾고 싶습니다. 스레드 수/최대 수 최대 성능 및 전체 리소스 활용률을 달성하기 위해 위에서 언급 한 시스템 구성을 기반으로 샘플 응용 프로그램에 대한 스레드 수를 계산합니다. – Santosh

+1

'경험적'답변을 원하지 않는다면 남은 것은 실험 디자인입니다. 몇 가지 설정을 시도하면 확실히 로컬 맥시마/미니 마를 찾을 수 있습니다. –

답변

57

최적의 스레드 수는 여러 요소에 따라 다르지만 대부분 사용 가능한 프로세서 수와 CPU 사용량이 많은 작업에 따라 다릅니다.

N_threads = N_cpu * U_cpu * (1 + W/C) 

:

  • N_threads은 최적의 스레드 수는
  • N_cpu 당신이 얻을 수 prcessors의 수입니다 Java Concurrency in Practice은 최적의 스레드 수를 추정하기 위해 다음과 같은 형식적인 공식을 제안한다 Runtime.getRuntime().availableProcessors();
  • U_cpu는 사용 가능한 전체 리소스를 사용하려는 경우 1입니다.
  • W/C는 t입니다. (예 : CPU 바운드 작업의 경우 0, 느린 I/O 작업의 경우 10 또는 100)

예를 들어 CPU 바운드 시나리오에서 스레드 수는 CPU (그 숫자 + 1을 사용하는 옹호자 중 한 명이지만, 그것이 중요한 차이를 만든다는 것을 본 적이 없다).

웹 크롤러와 같이 느린 I/O 프로세스의 경우 페이지 다운로드가 처리 속도보다 10 배 느리면 W/C가 10이 될 수 있습니다.이 경우 100 개의 스레드를 사용하면 유용합니다.

실제로 상한선이 있습니다 (10,000 개의 스레드를 사용하면 일반적으로 작업 속도가 향상되지 않으며 일반 메모리 설정으로는 모두 시작하기 전에 OutOfMemoryError가 발생합니다).

이것은 응용 프로그램이 실행되는 환경에 대해 알지 못하는 경우 얻을 수있는 최선의 예상 일 것입니다. 프로덕션 환경에서 응용 프로그램을 프로파일 링하면 설정을 세부 조정할 수 있습니다.

엄격하게 관련되어 있지는 않지만 프로그램 병렬화에서 기대할 수있는 최대 속도를 측정하는 것을 목표로하는 Amdahl's law에 관심이있을 수 있습니다.

+2

아, 좋은 지적, 내 이전의 코멘트를 제거. –

+0

견적을 얻으려면 어떻게해야합니까? I/O 대 Compute의 정확한 시간을 찾아야합니까? – AgentX

14

이 같은 JVM에 사용 가능한 프로세서의 수를 얻을 수 있습니다 :

Runtime.getRuntime().availableProcessors() 

가능한 프로세서의 수에서 최적의 스레드 수를 계산한다 불행히도 사소한 그러나. 이것은 응용 프로그램의 특성에 많이 달려 있습니다. 예를 들어, CPU 수의 응용 프로그램이 프로세서 수보다 많은 스레드를 사용하는 경우에는 의미가 없지만 응용 프로그램이 대부분 IO 바인딩 인 경우 스레드를 더 많이 사용할 수 있습니다. 시스템에서 다른 자원 집약적 인 프로세스가 실행 중일 경우 고려해야합니다.

최적의 전략은 각 하드웨어 구성에 대해 경험적으로 최적의 스레드 수를 결정한 다음 응용 프로그램에서이 수를 사용하는 것이 가장 좋습니다.

+0

Mine은 CPU 집약적 인 프로세스입니다. 또한 특정 h/w 구성에 대한 기준을 설정하는 방법에 대한 내용을 읽을 수 있습니까? 특정 프로세서가 사용 가능한 모든 리소스를 사용할 수 있는지 또는 다른 소프트웨어가 실행되고있어 차단 된 것인지 확인할 수있는 방법. – Santosh

+3

@Santosh CPU를 많이 사용하는 경우 스레드의'availableProcessors()'수를 사용하면 최적에 가깝습니다. – assylias

+0

보통 스레드 중 하나가 IO 또는 다른 것으로 막히는 경우를 대비하여 스케줄 슬롭을 선택하기 위해 작은 상수 요소를 추가합니다. –

2

VisualVm 도구를 사용하여 스레드를 모니터링하십시오. 우선 프로그램의 최소 스레드를 만들고 성능을 확인하십시오. 프로그램 내의 스레드 수를 늘리면 성능이 다시 분석됩니다. 도움이 될지 모르겠습니다.

15

내 권장 사항은 컴퓨터 당 스레드 수를 할당하기위한 구성 및 명령 줄 스위치를 제공하는 것입니다. user/admin이 명시 적으로 응용 프로그램을 다르게 구성하지 않은 경우 여기에 다른 응답에 표시된대로 Runtime.getRuntime(). availableProcessors()를 기반으로 한 경험적 방법을 사용하십시오. 나는 강하게은에 추천 고급 휴리스틱 기반의 스레드에 코어 여러 가지 이유로 추측 : 인텔의 같은 SMT 모델 :

  • 대부분의 최신 하드웨어 '하드웨어 스레드'의 점점 모호 유형으로 이동 하이퍼 스레딩과 AMD의 컴퓨 트 모듈은 수식 (아래 세부 정보)을 복잡하게하며 런타임에이 정보를 쿼리하는 것이 어려울 수 있습니다.

  • 대부분의 최신 하드웨어에는 활성 코어 및 주변 온도에 따라 속도가 조정되는 터보 기능이 있습니다. 터보 기술이 향상됨에 따라 속도 범위 (ghz)가 커집니다. 일부 최신 Intel 및 AMD 칩은 2.6GHz (모든 코어 활성화)에서 3.6ghz (단일/듀얼 코어 활성)까지 다양하며 SMT와 결합하면 각 스레드가 이전 설계에서 1.6GHz ~ 2.0GHz의 효율적인 처리량을 얻을 수 있습니다. 현재 런타임에이 정보를 쿼리 할 수있는 방법이 없습니다.

  • 응용 프로그램이 대상 시스템에서 실행되는 유일한 프로세스라는 강력한 보장이 없다면 모든 CPU 리소스를 맹목적으로 사용하면 소프트웨어가 사용자인지 여부에 따라 사용자 또는 서버 관리자에게 만족하지 못할 수 있습니다 앱 또는 서버 앱).

자신의 가정 압연 멀티 태스킹 커널 전체 운영 체제를 교체하지 않고, 실행시 시스템의 나머지 부분에서 무슨 일이 일어나고 있는지 알 수있는 강력한 방법이 없습니다. 귀하의 소프트웨어는 프로세스를 쿼리하고 CPU 부하 등을 들여다 보면서 숙련 된 추측을 시도 할 수 있지만 그렇게하면 복잡하고 유용성이 특정 유형의 응용 프로그램 (귀하가 자격을 가질 수있는 응용 프로그램)으로 제한되며 일반적으로 승격 또는 특권이 필요합니다. 액세스 수준.

  • 최신 바이러스 스캐너는 현대 운영 체제에서 제공하는 특별한 우선 순위 플래그를 설정하여 작동합니다. OS가 "시스템이 유휴 상태"일 때 알려줍니다. OS는 CPU 부하뿐만 아니라 영화 플레이어 등으로 설정되었을 수있는 사용자 입력 및 멀티미디어 플래그를 고려합니다.이것은 주로 유휴 작업에는 적합하지만 사용자와 같은 CPU 집중 작업에는 유용하지 않습니다.

  • 분산 된 가정용 컴퓨팅 응용 프로그램 (BOINC, Folding @ Home 등)은 주기적으로 실행중인 프로세스와 시스템 CPU로드를 정기적으로 쿼리하여 작동합니다 (매 초 또는 0.5 초마다). 행에있는 여러 쿼리에 대해 앱에 속하지 않는 프로세스에서로드가 감지되면 앱에서 계산을 일시 중단합니다. 일부 쿼리의로드가 낮아지면 다시 시작됩니다. CPU 부하 판독 값이 짧은 순간에 악명이 높기 때문에 여러 쿼리가 필요합니다. 여전히주의해야 할 사항이 있습니다. 1. 사용자는 BOINC를 기계 사양에 맞게 수동으로 다시 구성하는 것이 좋습니다. 2. BOINC가 관리자 권한없이 실행되면 다른 사용자 (일부 서비스 프로세스 포함)가 시작한 프로세스를 인식하지 못하기 때문에 CPU 자원과 부당하게 경쟁 할 수 있습니다.

에 관한 SMT (하이퍼 스레딩, 컴퓨팅 모듈) :

대부분의 SMTS 하드웨어 코어로보고하거나 것은 일부 응용 프로그램은 최적의 성능 때문에 모든 코어를 통해 확장 할 때 일반적으로 좋지 않은 요즘, 스레드 SMT 시스템. 설상가상으로 코어가 공유되는지 (SMT) 또는 전용인지를 쿼리하는 것은 종종 예상 결과를 산출하지 못합니다. 경우에 따라 OS 자체만으로는 알 수 없습니다 (예 : Windows 7은 AMD Bulldozer의 공유 코어 설계를 인식하지 못합니다). 신뢰할 수있는 SMT 카운트를 얻을 수 있다면, 각 SMT를 CPU 집약적 인 작업의 경우 절반 스레드로, 주로 유휴 작업의 경우 전체 스레드로 계산하는 것이 좋습니다. 그러나 실제로 SMT의 중요도는 어떤 일종의 계산과 목표 아키텍처에 달려 있습니다. Intel과 AMD의 SMT 구현은 거의 정반대의 동작을합니다. 예를 들어, Intel은 정수 및 분기 연산이 병렬로로드 된 작업을 실행하는 데 강합니다. AMD는 SIMD와 메모리 연산을 병렬로 실행하는 데 강합니다.

에 관한 터보 기능 :

대부분의 CPU가 요즘 매우 효과적 내장되어 더욱 줄여 터보 지원하는 가치를 얻을 수있는 시스템의 모든 코어에 걸쳐 확장에서. 더욱이 터보 기능은 때때로 CPU 부하에 따라 시스템의 실제 온도에 기반을두기 때문에 타워 자체의 냉각 시스템이 CPU 사양만큼 속도에 영향을 미칩니다. 예를 들어, 특정 AMD A10 (불도저)에서, 나는 그것이 두 스레드에서 3.7ghz에서 실행되는 것을 관찰했습니다. 세 번째 쓰레드가 시작될 때 3.5ghz로 떨어졌고 네 번째 쓰레드가 시작될 때 3.4ghz로 떨어졌습니다. 통합 된 GPU이기 때문에 4 개의 스레드와 GPU가 작동 할 때 약 3.0ghz로 떨어졌습니다 (A10 CPU는 내부적으로 고부하 시나리오에서 GPU에 우선 순위를 부여 함). 하지만 여전히 2 스레드와 GPU를 사용하여 3.6ghz를 소집 할 수 있습니다. 내 응용 프로그램이 CPU와 GPU를 모두 사용했기 때문에 이것은 중요한 발견이었습니다. 프로세스를 두 개의 CPU 바인딩 된 스레드로 제한하여 전체 성능을 향상시킬 수있었습니다 (다른 두 공유 코어는 여전히 도움이되었습니다. GPU를 서비스하는 스레드 역할을했기 때문에 빠르게 깨어나서 새로운 데이터를 GPU에 푸시 할 수있었습니다. 필요에 따라).

... 동시에 4x 스레드에서의 나의 응용 프로그램은 고품질 냉각 장치가 설치된 시스템에서 훨씬 더 잘 수행되었을 수 있습니다. 모두 매우 복잡합니다.

결론 : 좋은 대답은 없으며 CPU SMT/터보 디자인 분야가 계속 진화하고 있기 때문에 조만간 좋은 답변이 될 것으로 생각됩니다. 오늘 공식화 된 괜찮은 경험적 발견법은 내일 이상적인 결과를 내지 못할 것입니다. 그래서 제 권고안은 그것에 많은 시간을 낭비하지 마십시오. 거친 추측은 지역의 목적에 충분히 부합하는 코어 수를 기반으로 무언가를 추측하여 config/switch에 의해 무시되고 계속 진행되도록합니다.

4

다른 답변에 동의하는 것이 최선의 추측 방법이며 기본값을 재정의하기위한 구성을 제공합니다.

또한 응용 프로그램이 특히 CPU를 많이 사용하는 경우 특정 응용 프로그램에 응용 프로그램을 "고정"할 수 있습니다.

기본 운영 체제가 무엇인지 또는 여러 운영 체제를 지원하는지 여부는 알 수 없지만 대부분이 방법 중 일부는 있습니다. 예를 들어 리눅스는 taskset입니다.

일반적으로 CPU 0 (항상 OS에서 사용)을 피하고 응용 프로그램의 CPU 선호도를 동일한 소켓에있는 CPU 그룹에 설정합니다.

응용 프로그램 스레드를 CPU 0 (가능한 경우 다른 응용 프로그램과 멀리 떨어져있는 상태)에두면 작업 전환이 줄어들어 성능이 향상되는 경우가 있습니다.

하나의 소켓에 응용 프로그램을 유지하면 응용 프로그램의 스레드가 CPU간에 전환 될 때 캐시 무효화를 줄여 성능을 더욱 향상시킬 수 있습니다.

다른 모든 것들과 마찬가지로 이것은 실행중인 시스템의 아키텍처와 다른 응용 프로그램이 실행되는 위치에 따라 크게 달라집니다.

1

여기이 Python 스크립트를 사용하여 최적의 매개 변수 및 인체 공학으로 Java 응용 프로그램을 시작하는 코어 (및 메모리 등)의 수를 결정합니다. PlatformWise on Github

다음과 같이 작동합니다. 위의 스크립트에서 getNumberOfCPUCores()을 호출하여 코어 수를 얻고, getSystemMemoryInMB()을 사용하여 RAM을 얻는 python 스크립트를 작성하십시오. 명령 줄 인수를 통해 프로그램에 해당 정보를 전달할 수 있습니다. 그런 다음 프로그램은 코어 수에 따라 적절한 수의 스레드를 사용할 수 있습니다.

1

응용 프로그램 수준에서 스레드를 만드는 것이 좋으며 멀티 코어 프로세서에서는 별도의 스레드가 성능을 향상시키기 위해 코어에서 실행됩니다. 따라서 코어 처리 성능을 활용하려면 스레드를 구현하는 것이 가장 좋습니다.

내가 생각하는 것 :

  1. 프로그램의 1 스레드 1 개 코어에서 실행됩니다 한 번에.
  2. 2 스레드의 동일한 응용 프로그램은 2 코어의 절반 시간에 실행됩니다.
  3. 4 개의 스레드가있는 동일한 응용 프로그램은 4 코어에서 더 빠르게 실행됩니다.

그래서 당신이 개발하는 응용 프로그램은 = 코어의 어떤을 스레딩 수준 <가 없어야한다.

스레드 실행 시간은 운영 체제에서 관리하며 매우 예측할 수없는 작업입니다. CPU 실행 시간은 시간 조각 또는 양자라고합니다. 점점 더 많은 스레드를 생성하면 운영 체제는 어느 스레드가 먼저 가는지 결정할 때이 시간 조각의 일부를 소비하므로 각 스레드가 실제로 실행하는 시간이 단축됩니다. 즉, 많은 수의 스레드가 대기중인 경우 각 스레드는 더 적은 작업을 수행합니다.

실제로 CPU 코어를 활용하는 방법을 알아 보려면이 내용을 읽으십시오. 환상적인 컨텐츠. csharp-codesamples.com/2009/03/threading-on-multi-core-cpus/

1

그러나 사용 가능한 프로세서 수에서 최적의 스레드 수를 계산하는 것은 불행히도 사소하지 않습니다. 이것은 응용 프로그램의 특성에 많이 달려 있습니다. 예를 들어, CPU 수의 응용 프로그램이 프로세서 수보다 많은 스레드를 사용하는 경우에는 의미가 없지만 응용 프로그램이 대부분 IO 바인딩 인 경우 스레드를 더 많이 사용할 수 있습니다. 시스템에서 다른 자원 집약적 인 프로세스가 실행 중일 경우 고려해야합니다.