더 많은 스레드를 사용하는 것이 더 적은 스레드를 사용하는 것보다 더 느린 이유


29

8 개의 스레드를 사용하여 프로그램 X를 실행하려고 시도 했지만 n 분 후에 종료되었습니다 . 50 개의 스레드를
사용하여 동일한 프로그램을 실행하려고 시도 했지만 n * 10 분 안에 끝났습니다 .

왜 이런 일이 발생하며 어떻게 사용할 수있는 최적의 스레드 수를 얻을 수 있습니까?

답변:


33

이것은 당신이 묻는 복잡한 질문입니다. 스레드의 특성에 대해 더 많이 알지 못하면 말하기가 어렵습니다. 시스템 성능을 진단 할 때 고려해야 할 사항 :

프로세스 / 스레드인가

  • CPU 바운드 (많은 CPU 리소스 필요)
  • 메모리 바운드 (많은 RAM 리소스 필요)
  • I / O 바운드 (네트워크 및 / 또는 하드 드라이브 리소스)

이 세 가지 자원은 모두 유한하며 어느 하나의 시스템 성능을 제한 할 수 있습니다. 특정 상황이 어느 것을 소비하고 있는지 (2 또는 3 일 수 있음) 확인해야합니다.

당신은 사용 ntop하고 iostat, 그리고 vmstat에 무슨 일이 일어나고 있는지를 진단 할 수 있습니다.


8
하드웨어도 중요합니다. 물리적, 가상, 코어 수, 코어 유형, L1 / L2 / L3 캐시 등
EightBitTony

45

"왜 이런 일이 발생합니까?" 대답하기 쉽습니다. 네 사람이 나란히 앉을 수있는 복도가 있다고 상상해보십시오. 모든 쓰레기를 한쪽 끝에서 다른 쪽 끝으로 옮기고 싶습니다. 가장 효율적인 인원은 4 명입니다.

1 ~ 3 명인 경우 복도 공간을 사용할 수 없습니다. 5 명 이상의 사람들이 있다면, 그 사람들 중 적어도 하나는 기본적으로 항상 다른 사람 뒤에 대기하고 있습니다. 점점 더 많은 사람들을 추가하면 복도가 막히고 활동 속도가 빨라지지 않습니다.

따라서 대기열을 만들지 않고도 최대한 많은 사람을 수용 할 수 있습니다. 큐잉 (또는 병목 현상)이 발생하는 이유 는 slm의 답변에 따라 다릅니다.


1
당신의 모범은 오도합니다. "당신은 네 사람을 나란히 맞출 수있는 복도가 있고 그것은 당신 다른 사람들이 다른 작업을 위해 사용합니다. 복도를 통과 할 수있는 사람을 결정하는 심판이 있습니다. "가장 효율적인 사람들의 수는 4보다 크고 어떤 사람들보다 적습니다. 여기서 사람들은 줄을 서기 시작합니다." 일반적으로 몇 개의 스레드가 CPU 수보다 많으면 정확히 4 개의 스레드를 사용 하는 것보다 성능이 좋습니다 . 당신이 CPU를 사용 하는 유일한 사람이라면 4, 가장 좋은 숫자입니다.
Bakuriu

7
좋은 예, +1 Bakuriu는 제한된 공유 리소스의 문제를 보여주는 예입니다. 최적의 스레드 수를 찾는 방법이 아니라 문제를 설명합니다.
Bananguin

1
스레드에는 여전히 고유 한 유형의 컨텍스트 전환이 있음을 명심하는 것이 유용합니다. 스레드 수를 늘리더라도 성능 용량이 증가하지는 않지만 (지시 한대로) 커널에 더 많은 작업을 수행하여 CPU 시간이 소모됩니다. 기본적으로 스레딩에 대한 수익이 줄어들고 너무 많이 수행하면 성능이 저하됩니다.
Bratchley

9
모든 문제는 여러 수준의 복잡성에서 설명 할 수 있습니다. 나는 문제에 대한 근사치를 제시했으며 기본 사항을 설명하는 데 유용하다고 생각합니다. 물론 더 정교하고 상세 할 수는 있지만 더 자세하게 만들면 문제를 소개하는 데 덜 유용합니다.
EightBitTony

최적의 스레드 수를 계산하는 데 많은 시간을 소비하는 대신 쉽게 변경할 수 있도록 코드를 작성하면됩니다. 이와 같이 큰 병합을 수행하려면 완벽하게 테스트하기 위해 수많은 테스트 실행이 필요합니다 (대부분의 작은 데이터 하위 집합으로). 성능이 크게 저하되거나 다른 시스템 활동에 미치는 영향이 허용되지 않을 때까지 스레드 수를 늘리십시오.
DocSalvager

20

일반적인 권장 사항은 n + 1 스레드이며, n은 사용 가능한 CPU 코어 수입니다. 이렇게하면 1 개의 스레드가 디스크 I / O를 기다리는 동안 n 개의 스레드가 CPU를 작동 할 수 있습니다. 스레드 수가 적을수록 CPU 리소스를 완전히 활용하지 못하고 (어느 시점에 항상 대기 할 I / O가 있음) 스레드가 많으면 스레드가 CPU 리소스를 놓고 싸우게됩니다.

스레드는 사용 가능하지 않지만 컨텍스트 스위치와 같은 오버 헤드가 있으며 일반적으로 스레드간에 데이터를 교환해야하는 경우 다양한 잠금 메커니즘이 있습니다. 실제로 코드를 실행하기 위해 더 많은 전용 CPU 코어가있는 경우에만 비용이 가치가 있습니다. 단일 코어 CPU에서 단일 프로세스 (별도의 스레드 없음)는 일반적으로 스레딩보다 빠릅니다. 스레드는 마술처럼 CPU를 더 빠르게 만들지 않으며 추가 작업을 의미합니다.


문제가되는 정보의 양을 감안할 때 일반적인 답변이어야합니다. 우리는 다른 답변들처럼 완전한 논문과 철학이 필요하지 않습니다
Allahjane

8

다른 사람들이 지적했듯이 ( slm answer , EightBitTony answer ) 이것은 복잡한 질문이며, 무엇 을했는지와 그들이 어떻게하는지 설명하지 않기 때문에 더 복잡 합니다.

그러나 분명히 더 많은 스레드를 던지면 상황이 악화 될 수 있습니다.

병렬 컴퓨팅 분야에는 적용 할 수 있거나 문제의 세부 사항을 설명 할 수는 없지만 암달의 법칙 이 있으며 이러한 종류의 문제에 대한 일반적인 통찰력을 줄 수 있습니다.

Amdahl의 법칙의 요점은 모든 프로그램 (모든 알고리즘)에서 항상 병렬 실행할 수없는 백분율 ( 순차 부분 )이 있고 병렬 실행할 수있는 다른 백분율 ( 병렬 부분 )이 있다는 것입니다. 이들 두 부분은 100 %가된다.

이 부분은 실행 시간의 백분율로 표현할 수 있습니다. 예를 들어, 엄격하게 순차적 인 작업에 25 %의 시간이 소요될 수 있으며 나머지 75 %의 시간은 병렬로 실행될 수있는 작업에 소비됩니다.

Wikipedia의 이미지 ( 위키 백과의 이미지 )

암달의 법칙에 따르면 프로그램의 주어진 모든 병렬 부분 (예 : 75 %)에 대해 더 많은 프로세서를 사용하여 작업을 수행하더라도 지금까지만 (최대 4 회) 실행 속도를 높일 수 있다고 예측합니다.

경험상 병렬 실행으로 변환 할 수없는 프로그램이 많을수록 더 많은 실행 단위 (프로세서)를 사용하여 얻을 수있는 양이 줄어 듭니다.

실제 프로세서가 아닌 스레드를 사용한다고 가정하면 상황이 이보다 더 나빠질 수 있습니다. 스레드는 동일한 물리적 프로세서 / 코어를 공유 하는 (구현 및 하드웨어 (예 : CPU / 코어 등)에 따라) 처리 될 수 있습니다 ( 다른 답변에서 지적한 바와 같이 멀티 태스킹의 한 형태 임).

이 엄밀한 예측 (약 CPU 시간)은 다른 실제 병목 현상을 다음과 같이 고려하지 않습니다.

  1. 제한된 I / O 속도 (하드 디스크 및 네트워크 "속도")
  2. 메모리 크기 제한
  3. 기타

실제 응용 분야에서 쉽게 제한 요소가 될 수 있습니다.


답변을 선택해야합니다.
Eonil

6

여기서 범인은 "컨텍스트 스위칭"이어야합니다. 현재 스레드 상태를 저장하여 다른 스레드 실행을 시작하는 프로세스입니다. 여러 스레드에 동일한 우선 순위가 부여되면 실행이 완료 될 때까지 전환해야합니다.

귀하의 경우 50 개의 스레드가있을 때 10 개의 스레드를 실행하는 것과 비교할 때 많은 컨텍스트 전환이 발생합니다.

컨텍스트 전환으로 인한 오버 헤드는 프로그램을 느리게 만드는 원인입니다.


우리는 스레드가 무엇인지 알지 못하기 때문에 추측으로 보입니다. 컨텍스트 전환은 오버 헤드를 추가하지만 스레드가 일종의 데이터 분석을 수행하는 경우 캐시 문제 일 수 있습니다 (즉, 스레드를 전환 할 때마다 캐시를 ​​플러시해야하기 때문에 캐시를 사용할 수 없음).
EightBitTony

많은 수의 컨텍스트 스위치를 다루지 않는 한 스레드 컨텍스트 전환 자체 는 성능에 큰 영향을 미치지 않을 것입니다. 50 개의 스레드는 높지만 극단적이지는 않습니다 (지금은 상자에 225 개의 프로세스 가보고되며 결코로드되지 않습니다). 나는 @EightBitTony의 추측과 함께 가고 싶어한다; 캐시 무효화마다 캐시를 플러시 때문에, CPU는 기다려야 가능성이 더 큰 문제입니다 옛날 RAM에서 코드와 데이터를. ps ax | wc -l
CVn

2

EightBitTony의 은유를 수정하려면 :

"왜 이런 일이 발생합니까?" 대답하기 쉽습니다. 수영장 하나가 비어 있고 수영장 하나 가 있다고 상상해보십시오 . 모든 물을 한곳에서 다른 곳으로 옮기고 4 개의 양동이가 있습니다. 가장 효율적인 인원은 4 명입니다.

1 ~ 3 명인 경우 일부 버킷 을 사용하지 못하게됩니다 . 사람이 5 명 이상인 경우 해당 사람 중 적어도 하나가 버킷을 기다리는 중입니다 . 점점 더 많은 사람을 추가해도 활동 속도가 빨라지지 않습니다.

따라서 몇 가지 작업 (버킷 사용)을 동시에 수행 할 수있는 많은 사람을 원합니다 .

여기서 사람은 스레드이며 버킷은 실행 리소스 중 병목 현상이 발생하는 것을 나타냅니다. 스레드를 추가해도 아무 것도 할 수없는 경우 도움이되지 않습니다. 또한, 한 사람에서 다른 사람으로 버킷전달하는 것은 일반적으로 한 사람이 동일한 거리에서 버킷을 운반하는 것보다 느리다는 점 강조해야합니다 . 즉, 코어를 켜는 두 스레드는 일반적으로 두 번 실행되는 단일 스레드보다 적은 작업을 수행합니다. 이는 두 스레드 사이를 전환하기 위해 수행되는 추가 작업 때문입니다.

제한 실행 리소스 (버킷)가 CPU인지 코어인지 또는 하이퍼 스레딩 명령 파이프 라인인지 여부는 아키텍처의 어느 부분이 제한 요소인지에 따라 다릅니다. 또한 우리는 스레드가 완전히 독립적 이라고 가정합니다 . 데이터 를 공유 하지 않고 캐시 충돌을 피하는 경우에만 해당됩니다 .

두 사람이 제안한 바와 같이, I / O의 경우 제한 리소스는 유용하게 큐에 넣을 수있는 I / O 작업의 수일 수 있습니다. 이는 전체 하드웨어 및 커널 요소에 따라 달라질 수 있지만 그 수보다 훨씬 클 수 있습니다. 코어. 여기서 실행 바인딩 코드와 비교하여 비용이 많이 드는 컨텍스트 스위치는 I / O 바인딩 코드에 비해 상당히 저렴합니다. 슬프게도 양동이로 이것을 정당화하려고하면 은유가 완전히 통제되지 않을 것이라고 생각합니다.

있습니다 최적의 I / O 바운드 코드의 동작은 일반적으로 여전히 파이프 라인 / 코어 / CPU 당 최대 하나 개의 스레드에서 가지고. 그러나 비동기식 또는 동기식 / 비 차단 I / O 코드를 작성해야하며 상대적으로 작은 성능 향상이 항상 추가 복잡성을 정당화하지는 않습니다.


추신. 원래 복도 은유에 대한 나의 문제는 4 개의 대기열을 가질 수 있어야하며 2 개의 대기열은 쓰레기를 운반하고 2 개의 대기열은 더 많은 것을 수집하기 위해 돌아 오는 것이 좋습니다. 그런 다음 복도만큼 거의 각 대기열을 만들 수 있으며 사람들을 추가 하면 알고리즘 속도 빨라졌습니다 (기본적으로 전체 복도를 컨베이어 벨트로 바꿨습니다).

실제로이 시나리오는 TCP 네트워킹에서 대기 시간과 창 크기 사이의 관계에 대한 표준 설명과 매우 유사하므로 나에게 튀어 나온 이유입니다.


그것은 은유가 아니며 사람들이 쉽게 시각화 할 수있는 방식으로 사람들에게 시스템을 설명하기 위해 고안된 근사치입니다. 따라서 다음 단계의 세부 사항을 알고 있지만 초보자에게는 실제로 세부 수준이 필요하지 않다는 사실을 모르는 사람들은 항상 '쓰레기'가 될 것입니다. PhD 수준에서 시작하여 입자 물리학을 배우는 사람은 없습니다. 이전의 모든 것들은 그들이 당신을 점점 점진적으로 이끌어가는 근사치입니다. 그것은 '잘못'이 아닙니다. 그것은 전체 그림이 아닙니다.
EightBitTony 2016 년

어느 연설을 사용했는지 혼동하는 사람은 없으며 그다지 비유가 아닙니다. 모든 비유에는 설명해야 할 것과 다른 한계가 있으며 유용하지 않습니다. 나는 원본이 나에게 다른 시나리오를 강력하게 상기 시켰기 때문에 (이것은) 희망적으로 개선 된 예측에 대해 더 복잡한 것으로 생각하지 않기 때문에 이것을 언급했다.
쓸모없는

0

이해하기 쉽고 간단합니다. CPU가 지원하는 것보다 많은 스레드가 있으면 실제로 직렬화되고 병렬화되지 않습니다. 스레드가 많을수록 시스템 속도가 느려집니다. 결과는 실제로이 현상의 증거입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.