답변:
이것은 당신이 묻는 복잡한 질문입니다. 스레드의 특성에 대해 더 많이 알지 못하면 말하기가 어렵습니다. 시스템 성능을 진단 할 때 고려해야 할 사항 :
프로세스 / 스레드인가
이 세 가지 자원은 모두 유한하며 어느 하나의 시스템 성능을 제한 할 수 있습니다. 특정 상황이 어느 것을 소비하고 있는지 (2 또는 3 일 수 있음) 확인해야합니다.
당신은 사용 ntop
하고 iostat
, 그리고 vmstat
에 무슨 일이 일어나고 있는지를 진단 할 수 있습니다.
"왜 이런 일이 발생합니까?" 대답하기 쉽습니다. 네 사람이 나란히 앉을 수있는 복도가 있다고 상상해보십시오. 모든 쓰레기를 한쪽 끝에서 다른 쪽 끝으로 옮기고 싶습니다. 가장 효율적인 인원은 4 명입니다.
1 ~ 3 명인 경우 복도 공간을 사용할 수 없습니다. 5 명 이상의 사람들이 있다면, 그 사람들 중 적어도 하나는 기본적으로 항상 다른 사람 뒤에 대기하고 있습니다. 점점 더 많은 사람들을 추가하면 복도가 막히고 활동 속도가 빨라지지 않습니다.
따라서 대기열을 만들지 않고도 최대한 많은 사람을 수용 할 수 있습니다. 큐잉 (또는 병목 현상)이 발생하는 이유 는 slm의 답변에 따라 다릅니다.
4
, 가장 좋은 숫자입니다.
일반적인 권장 사항은 n + 1 스레드이며, n은 사용 가능한 CPU 코어 수입니다. 이렇게하면 1 개의 스레드가 디스크 I / O를 기다리는 동안 n 개의 스레드가 CPU를 작동 할 수 있습니다. 스레드 수가 적을수록 CPU 리소스를 완전히 활용하지 못하고 (어느 시점에 항상 대기 할 I / O가 있음) 스레드가 많으면 스레드가 CPU 리소스를 놓고 싸우게됩니다.
스레드는 사용 가능하지 않지만 컨텍스트 스위치와 같은 오버 헤드가 있으며 일반적으로 스레드간에 데이터를 교환해야하는 경우 다양한 잠금 메커니즘이 있습니다. 실제로 코드를 실행하기 위해 더 많은 전용 CPU 코어가있는 경우에만 비용이 가치가 있습니다. 단일 코어 CPU에서 단일 프로세스 (별도의 스레드 없음)는 일반적으로 스레딩보다 빠릅니다. 스레드는 마술처럼 CPU를 더 빠르게 만들지 않으며 추가 작업을 의미합니다.
다른 사람들이 지적했듯이 ( slm answer , EightBitTony answer ) 이것은 복잡한 질문이며, 무엇 을했는지와 그들이 어떻게하는지 설명하지 않기 때문에 더 복잡 합니다.
그러나 분명히 더 많은 스레드를 던지면 상황이 악화 될 수 있습니다.
병렬 컴퓨팅 분야에는 적용 할 수 있거나 문제의 세부 사항을 설명 할 수는 없지만 암달의 법칙 이 있으며 이러한 종류의 문제에 대한 일반적인 통찰력을 줄 수 있습니다.
Amdahl의 법칙의 요점은 모든 프로그램 (모든 알고리즘)에서 항상 병렬 로 실행할 수없는 백분율 ( 순차 부분 )이 있고 병렬 로 실행할 수있는 다른 백분율 ( 병렬 부분 )이 있다는 것입니다. 이들 두 부분은 100 %가된다.
이 부분은 실행 시간의 백분율로 표현할 수 있습니다. 예를 들어, 엄격하게 순차적 인 작업에 25 %의 시간이 소요될 수 있으며 나머지 75 %의 시간은 병렬로 실행될 수있는 작업에 소비됩니다.
( 위키 백과의 이미지 )
암달의 법칙에 따르면 프로그램의 주어진 모든 병렬 부분 (예 : 75 %)에 대해 더 많은 프로세서를 사용하여 작업을 수행하더라도 지금까지만 (최대 4 회) 실행 속도를 높일 수 있다고 예측합니다.
경험상 병렬 실행으로 변환 할 수없는 프로그램이 많을수록 더 많은 실행 단위 (프로세서)를 사용하여 얻을 수있는 양이 줄어 듭니다.
실제 프로세서가 아닌 스레드를 사용한다고 가정하면 상황이 이보다 더 나빠질 수 있습니다. 스레드는 동일한 물리적 프로세서 / 코어를 공유 하는 (구현 및 하드웨어 (예 : CPU / 코어 등)에 따라) 처리 될 수 있습니다 ( 다른 답변에서 지적한 바와 같이 멀티 태스킹의 한 형태 임).
이 엄밀한 예측 (약 CPU 시간)은 다른 실제 병목 현상을 다음과 같이 고려하지 않습니다.
실제 응용 분야에서 쉽게 제한 요소가 될 수 있습니다.
여기서 범인은 "컨텍스트 스위칭"이어야합니다. 현재 스레드 상태를 저장하여 다른 스레드 실행을 시작하는 프로세스입니다. 여러 스레드에 동일한 우선 순위가 부여되면 실행이 완료 될 때까지 전환해야합니다.
귀하의 경우 50 개의 스레드가있을 때 10 개의 스레드를 실행하는 것과 비교할 때 많은 컨텍스트 전환이 발생합니다.
컨텍스트 전환으로 인한 오버 헤드는 프로그램을 느리게 만드는 원인입니다.
ps ax | wc -l
EightBitTony의 은유를 수정하려면 :
"왜 이런 일이 발생합니까?" 대답하기 쉽습니다. 수영장 하나가 비어 있고 수영장 하나 가 있다고 상상해보십시오 . 모든 물을 한곳에서 다른 곳으로 옮기고 4 개의 양동이가 있습니다. 가장 효율적인 인원은 4 명입니다.
1 ~ 3 명인 경우 일부 버킷 을 사용하지 못하게됩니다 . 사람이 5 명 이상인 경우 해당 사람 중 적어도 하나가 버킷을 기다리는 중입니다 . 점점 더 많은 사람을 추가해도 활동 속도가 빨라지지 않습니다.
따라서 몇 가지 작업 (버킷 사용)을 동시에 수행 할 수있는 많은 사람을 원합니다 .
여기서 사람은 스레드이며 버킷은 실행 리소스 중 병목 현상이 발생하는 것을 나타냅니다. 스레드를 추가해도 아무 것도 할 수없는 경우 도움이되지 않습니다. 또한, 한 사람에서 다른 사람으로 버킷 을 전달하는 것은 일반적으로 한 사람이 동일한 거리에서 버킷을 운반하는 것보다 느리다는 점 을 강조해야합니다 . 즉, 코어를 켜는 두 스레드는 일반적으로 두 번 실행되는 단일 스레드보다 적은 작업을 수행합니다. 이는 두 스레드 사이를 전환하기 위해 수행되는 추가 작업 때문입니다.
제한 실행 리소스 (버킷)가 CPU인지 코어인지 또는 하이퍼 스레딩 명령 파이프 라인인지 여부는 아키텍처의 어느 부분이 제한 요소인지에 따라 다릅니다. 또한 우리는 스레드가 완전히 독립적 이라고 가정합니다 . 데이터 를 공유 하지 않고 캐시 충돌을 피하는 경우에만 해당됩니다 .
두 사람이 제안한 바와 같이, I / O의 경우 제한 리소스는 유용하게 큐에 넣을 수있는 I / O 작업의 수일 수 있습니다. 이는 전체 하드웨어 및 커널 요소에 따라 달라질 수 있지만 그 수보다 훨씬 클 수 있습니다. 코어. 여기서 실행 바인딩 코드와 비교하여 비용이 많이 드는 컨텍스트 스위치는 I / O 바인딩 코드에 비해 상당히 저렴합니다. 슬프게도 양동이로 이것을 정당화하려고하면 은유가 완전히 통제되지 않을 것이라고 생각합니다.
있습니다 최적의 I / O 바운드 코드의 동작은 일반적으로 여전히 파이프 라인 / 코어 / CPU 당 최대 하나 개의 스레드에서 가지고. 그러나 비동기식 또는 동기식 / 비 차단 I / O 코드를 작성해야하며 상대적으로 작은 성능 향상이 항상 추가 복잡성을 정당화하지는 않습니다.
추신. 원래 복도 은유에 대한 나의 문제는 4 개의 대기열을 가질 수 있어야하며 2 개의 대기열은 쓰레기를 운반하고 2 개의 대기열은 더 많은 것을 수집하기 위해 돌아 오는 것이 좋습니다. 그런 다음 복도만큼 거의 각 대기열을 만들 수 있으며 사람들을 추가 하면 알고리즘 속도 가 빨라졌습니다 (기본적으로 전체 복도를 컨베이어 벨트로 바꿨습니다).
실제로이 시나리오는 TCP 네트워킹에서 대기 시간과 창 크기 사이의 관계에 대한 표준 설명과 매우 유사하므로 나에게 튀어 나온 이유입니다.