멀티 스레딩 : 코어보다 더 많은 스레드의 요점은 무엇입니까?


142

멀티 코어 컴퓨터의 요점은 여러 스레드를 동시에 실행할 수 있다는 것입니다. 이 경우 쿼드 코어 머신을 사용하는 경우 한 번에 4 개 이상의 스레드가 실행되는 시점은 무엇입니까? 그들은 단지 서로에게서 시간을 훔치지 않을 것입니까 (CPU 리소스)?


52
우리는 그들이 granted..keep이 ..와 주셔서 촬영 무언가의 아주 근본적인 질문, 질문의이 유형을 즐길
스 리니 바스 레디 Thatiparthy

6
파이어 폭스, MS Word, Winamp, Eclipse 및 쿼드 코어 머신에서 동시에 다운로드 관리자 (4 개 이상의 프로그램 / 프로세스)를 실행 한 시간은 언제입니까? 또한 단일 응용 프로그램이 때때로 4 개 이상의 스레드를 생성 할 수 있습니다. 어떻습니까?
Amarghosh

1
도둑질이 반드시 나쁘지는 않습니다. 시간을 훔쳐 야하는 중요한 작업에 우선 순위가 높은 스레드가있을 수 있습니다.
kichik

1
@ Amarghosh 나는 이것이 하나의 응용 프로그램이 성능 이점을 가져 오지 않는 것처럼 코어보다 더 많은 스레드를 생성하려는 이유가 문제라고 생각합니다. 그리고 네 개 이상의 프로그램을 가진 당신의 예는 여기서 관련이 없습니다. 올바르게 언급했듯이 프로세스입니다. OS 멀티 태스킹 기능 (프로세스 멀티플렉싱)은 한 프로세스 내의 스레드와 거의 관련이 없습니다.
Aleksandr Ivannikov

답변:


81

대답은 스레드의 목적을 중심으로 진행되는데, 이는 병렬 처리입니다. 한 번에 여러 개의 개별 실행 라인을 실행하는 것입니다. '이상적인'시스템에서는 코어 당 하나의 스레드가 실행됩니다 (중단 없음). 실제로는 그렇지 않습니다. 4 개의 코어와 4 개의 작업 스레드가 있어도 프로세스 및 스레드는 다른 프로세스 및 스레드에 대해 지속적으로 전환됩니다. 최신 OS를 실행하는 경우 모든 프로세스에는 하나 이상의 스레드가 있으며 많은 스레드가 있습니다. 이 모든 프로세스는 한 번에 실행됩니다. 아마도 지금 당신의 컴퓨터에서 수백 개의 스레드가 모두 실행 중일 것입니다. 스레드가 시간을 도난 당하지 않고 스레드가 실행되는 상황은 없습니다. ( 실시간으로 실행 된다면실시간 OS를 사용하거나 Windows에서도 실시간 스레드 우선 순위를 사용하십시오. 그러나 드물다.)

그 배경으로 대답은 그렇습니다. 그렇습니다. 실제 4 코어 머신에서 4 개 이상의 스레드는 각각의 스레드가 100 % CPU를 필요로하는 경우에만 '서로 시간을 훔치는'상황을 제공 할 수 있습니다 . 스레드가 100 % 작동하지 않으면 (UI 스레드가 작동하지 않거나 약간의 작업을 수행하거나 다른 작업을 기다리는 스레드) 실제로 예약중인 다른 스레드가 좋은 상황입니다.

실제로는 그보다 더 복잡합니다.

  • 한 번에 모두 완료해야하는 5 비트 작업이있는 경우 어떻게합니까? 4 개를 실행 한 다음 5 번째를 실행하는 것보다 한 번에 모두 실행하는 것이 더 합리적입니다.

  • 스레드가 실제로 100 % CPU를 필요로하는 경우는 드 rare니다. 예를 들어, 디스크 또는 네트워크 I / O를 사용하는 순간, 아무 쓸모없는 작업을 기다리는 데 시간이 걸릴 수 있습니다. 이것은 매우 일반적인 상황입니다.

  • 실행해야하는 작업이있는 경우 일반적인 메커니즘 중 하나는 스레드 풀을 사용하는 것입니다. 코어와 동일한 수의 스레드를 갖는 것이 타당 할 수 있지만 .Net 스레드 풀에는 프로세서 당 최대 250 개의 스레드가 있습니다 . 나는 그들이 왜 이것을하는지 확실하지 않지만, 내 추측은 스레드에서 실행되도록 주어진 작업의 크기와 관련이 있습니다.

따라서 : 도둑질 시간은 나쁜 일이 아니며 (실제로 도난 당하지도 않습니다 : 시스템이 작동하는 방식입니다.) 스레드가 수행 할 작업의 종류에 따라 멀티 스레드 프로그램을 작성하십시오 .CPU가 아닐 수도 있습니다 -경계. 프로파일 링 및 측정에 따라 필요한 스레드 수를 파악하십시오. 스레드보다는 작업 또는 작업의 관점에서 생각하는 것이 더 유용 할 수 있습니다. 작업 개체를 작성하고 실행할 풀에 제공하십시오. 마지막으로, 프로그램이 성능에 중요하지 않으면 너무 걱정하지 마십시오. :)


16
"각 개별 스레드에 100 % CPU가 필요한 경우에만"+1 그것이 내가 만들고 있다는 것을 몰랐다는 가정이었습니다.
Nick Heiner 2016 년

1
훌륭한 질문에 대한 훌륭한 답변. 감사합니다!
Edgecase

53

스레드가 존재한다고해서 항상 스레드가 실행되고있는 것은 아닙니다. 스레드의 많은 응용 프로그램은 스레드가 무언가를 수행 할 시간이 될 때까지 일부 스레드가 잠기 게합니다.

기본적으로 스레드는 다른 작업의 진행 상황을 알 필요없이 서로 독립적으로 작동 할 수있는 개별 작업입니다. 동시에 실행할 수있는 것보다 더 많은 것을 가질 수 있습니다. 그들은 때때로 서로 뒤에 줄을 서서 기다려야 할지라도 편의상 여전히 유용합니다.


11
잘했다. 'CPU 당 하나의 스레드'인수는 CPU 바인딩 코드에만 적용됩니다. 비동기 프로그래밍은 스레드를 사용하는 또 다른 이유입니다.
Joshua Davis

26

요점은 스레드 수가 코어 수를 초과 할 때 실제 속도 향상을 얻지 못하더라도 스레드를 사용하여 상호 의존성이 없어야하는 논리 조각을 분리 할 수 ​​있다는 것입니다.

약간 복잡한 응용 프로그램에서도 단일 스레드를 사용하면 모든 작업을 신속하게 수행하여 코드의 '흐름'을 해시합니다. 단일 스레드는 대부분의 시간을 이것을 폴링하고,이를 확인하고, 필요에 따라 조건부로 루틴을 호출하며, 사소한 조악한 것을보기가 어려워집니다.

스레드를 작업 전용으로 사용하여 개별 스레드를보고 해당 스레드가 수행중인 작업을 확인할 수있는 경우와 비교하십시오. 예를 들어, 하나의 스레드가 소켓에서 입력 대기를 차단하고 스트림을 메시지로 구문 분석하고 메시지를 필터링하며 유효한 메시지가 나타나면 다른 작업자 스레드로 전달합니다. 작업자 스레드는 여러 다른 소스의 입력에서 작동 할 수 있습니다. 이들 각각에 대한 코드는 별도의 조치가 없는지 명시 적으로 확인할 필요없이 깨끗하고 목적이있는 흐름을 나타냅니다.

이러한 방식으로 작업을 분할하면 응용 프로그램이 운영 체제에 의존하여 CPU로 다음에 수행 할 작업을 예약 할 수 있으므로 응용 프로그램 내에서 차단할 수있는 항목과 처리 할 수있는 대상에 대한 조건부 검사를 명시 적으로 수행 할 필요가 없습니다.


1
이것은 흥미로운 생각입니다 ... 앱을 멀티 스레딩하는 것이 복잡성을 추가 한 것이라고 들었습니다. 그러나 여러분이 말하는 것은 말이됩니다.
Nick Heiner 2016 년

앱의 멀티 스레딩은 관심사가 적절히 분리되지 않은 경우 복잡성을 추가합니다. 문제의 중복을 최소화하고 공유 상태로 설계하면 복잡성 문제를 완전히 줄일 수 있습니다.
저의 정확한 의견 JUIN

단일 스레드 응용 프로그램을 구조화하여 프로그램을 작성하는 수준에서 제어 흐름이 더 명확 해 지도록하는 방법이 있습니다. OTOH, 스레드가 (자원을 공유하는 대신) 서로에게만 메시지를 전달하도록 스레드를 구성 할 수 있다면 진행중인 작업을 해결하고 모든 작업을 수행하는 것이 매우 간단합니다.
Donal Fellows

1
그러나 스레드를 사용하면 특정 지점까지만 단순화 할 수 있다는 점을 지적해야합니다. 너무나 자주 두 개의 스레드가 하나의 작업 만 수행하도록하려고 노력하는데,이 작업에서 복잡성은 스페이드로 되돌아옵니다. 이것의 증상은 원하는 결과를 조정하기 위해 통신 및 동기화에 대한 과도한 요구입니다.
JustJeff

15

스레드가 자원을 기다리고있는 경우 (예 : RAM에서 레지스터, 디스크 I / O, 네트워크 액세스로 값로드, 새 프로세스 시작, 데이터베이스 쿼리 또는 사용자 입력 대기 등) 프로세서는 리소스를 사용할 수있게되면 첫 번째 스레드로 돌아갑니다. CPU가 유휴 상태가 아닌 수백만 개의 작업을 수행 할 수 있기 때문에 CPU가 유휴 시간을 줄입니다.

하드 드라이브에서 데이터를 읽어야하는 스레드를 고려하십시오. 2014 년에 일반적인 프로세서 코어는 2.5GHz에서 작동하며 사이클 당 4 개의 명령을 실행할 수 있습니다. 사이클 시간이 0.4 ns 인 프로세서는 나노 초당 10 개의 명령을 실행할 수 있습니다. 일반적인 기계식 하드 드라이브 탐색 시간은 약 10 밀리 초이므로 프로세서는 하드 드라이브에서 값을 읽는 데 걸리는 시간에 1 억 개의 명령을 실행할 수 있습니다. 하이브리드 섹션에서 순차적 읽기 또는 읽기를위한 데이터 대기 시간이 몇 배 더 빠를 수 있으므로 작은 캐시 (4MB 버퍼)가있는 하드 드라이브와 몇 GB의 스토리지가있는 하이브리드 드라이브의 성능이 크게 향상 될 수 있습니다.

프로세서 코어는 스레드간에 전환 할 수 있으며 (스레드 일시 중지 및 재개 비용은 약 100 클럭주기) 첫 번째 스레드는 대기 시간이 긴 입력 (레지스터 (1 클럭) 및 RAM (5 나노초)보다 비싼 항목)을 기다립니다. 디스크 I / O, 네트워크 액세스 (대기 시간 250ms), CD 또는 느린 버스에서 데이터 읽기 또는 데이터베이스 호출 코어보다 많은 스레드가 있으면 대기 시간이 긴 작업이 해결되는 동안 유용한 작업을 수행 할 수 있습니다.

CPU에는 스레드 스케줄러가있어 각 스레드에 우선 순위를 지정하고 스레드를 휴면 상태로 설정 한 후 사전 결정된 시간 후에 다시 시작할 수 있습니다. 스레 싱을 줄이는 것은 스레드 스케줄러의 작업입니다. 각 스레드가 다시 잠자기 전에 100 개의 명령 만 실행하면 발생합니다. 스레드 전환의 오버 헤드는 프로세서 코어의 총 유용한 처리량을 줄입니다.

이러한 이유로 문제를 합리적인 수의 스레드로 나누고 싶을 수 있습니다. 행렬 곱셈을 수행하기위한 코드를 작성하는 경우 출력 행렬에서 셀당 하나의 스레드를 작성하는 것이 과도 할 수있는 반면 , 출력 행렬에서 행당 또는 행당 n 개의 행을 작성하면 스레드 작성, 일시 정지 및 재개에 드는 오버 헤드 비용이 줄어들 수 있습니다.

이것이 분기 예측이 중요한 이유이기도합니다. RAM에서 값을로드해야하는 if 문이 있지만 if 및 else 문의 본문은 이미 레지스터에로드 된 값을 사용하는 경우 프로세서는 조건이 평가되기 전에 하나 또는 두 개의 분기를 실행할 수 있습니다. 조건이 반환되면 프로세서는 해당 분기의 결과를 적용하고 다른 분기를 버립니다. 잠재적으로 쓸모없는 작업을 수행하는 것이 다른 스레드로 전환하는 것보다 낫습니다.

우리는 고속 단일 코어 프로세서에서 멀티 코어 프로세서로 이동함에 따라 칩 설계는 다이 당 더 많은 코어를 크 래밍하고 코어 간의 온칩 리소스 공유 개선, 분기 예측 알고리즘 개선, 스레드 전환 오버 헤드 개선, 더 나은 스레드 스케줄링.


단 하나의 스레드와 대기열로도 동일한 작업을 수행 할 수 있습니다. 그들은 할 일이 없습니까?
Dmitry

8

위의 답변 대부분은 성능과 동시 작동에 대해 이야기합니다. 나는 다른 각도에서 이것에 접근 할 것입니다.

간단한 터미널 에뮬레이션 프로그램을 예로 들어 봅시다. 다음을 수행해야합니다.

  • 원격 시스템에서 들어오는 문자를보고 표시합니다
  • 키보드에서 나오는 물건을보고 원격 시스템으로 보냅니다.

(실제 터미널 에뮬레이터는 입력 한 내용을 디스플레이에 에코하는 것을 포함하여 더 많은 작업을 수행하지만 지금은 그 내용을 전달할 것입니다.)

이제 다음 의사 코드에 따라 리모콘에서 읽는 루프가 간단합니다.

while get-character-from-remote:
    print-to-screen character

키보드를 모니터링하고 전송하는 루프도 간단합니다.

while get-character-from-keyboard:
    send-to-remote character

그러나 문제는이 작업을 동시에 수행해야한다는 것입니다. 스레딩이 없으면 코드는 다음과 같이 보입니다.

loop:
    check-for-remote-character
    if remote-character-is-ready:
        print-to-screen character
    check-for-keyboard-entry
    if keyboard-is-ready:
        send-to-remote character

통신의 실제 복잡성을 고려하지 않은이 의도적으로 단순화 된 예에서도 논리는 매우 난독 화됩니다. 그러나 스레딩을 사용하면 단일 코어에서도 두 개의 의사 코드 루프가 논리를 인터레이스하지 않고 독립적으로 존재할 수 있습니다. 두 스레드는 대부분 I / O 바운드이기 때문에 엄밀히 말하면 통합 루프보다 CPU 리소스가 더 낭비 되더라도 CPU에 많은 부하를주지 않습니다.

물론 실제 사용은 위의 것보다 더 복잡합니다. 그러나 애플리케이션에 더 많은 관심을 가짐에 따라 통합 루프의 복잡성이 기하 급수적으로 증가합니다. 논리는 점점 더 세분화되고 상태 머신, 코 루틴 등과 같은 기술을 사용하여 일을 관리해야합니다. 관리는 가능하지만 읽을 수는 없습니다. 스레딩은 코드를 더 읽기 쉽게 유지합니다.

그렇다면 왜 스레딩을 사용하지 않습니까?

작업이 I / O 바운드 대신 CPU 바운드 인 경우 스레딩은 실제로 시스템 속도를 저하시킵니다. 성능이 저하됩니다. 많은 경우에 많이 있습니다. ( "스 래싱 (Thrashing)"은 CPU 바운드 스레드를 너무 많이 삭제하면 일반적인 문제입니다. 스레드 자체의 내용을 실행하는 것보다 활성 스레드를 변경하는 데 더 많은 시간을 소비하게됩니다. 또한 위의 논리 중 하나는 매우 간단합니다. 저는 단순하고 비현실적인 예제를 고의적으로 선택했습니다. 화면에 입력 된 내용을 에코하려면 공유 리소스 잠금을 도입하면서 새로운 상처를 입게됩니다. 공유 리소스가 하나만 있으면 별 문제가되지 않지만 공유 할 리소스가 많을수록 더 큰 문제가되기 시작합니다.

결국 스레딩은 많은 것들에 관한 것입니다. 예를 들어, 일부 사람들이 이미 말했듯이 I / O 바운드 프로세스를 전반적으로 덜 효율적으로 만드는 것이 중요합니다. 또한 논리를 쉽게 따르기위한 것입니다 (공유 상태를 최소화 한 경우에만). 그것은 많은 것들에 관한 것이며, 사례별로 장점이 장점보다 큰지 결정해야합니다.


6

하드웨어에 따라 계산 속도를 높이기 위해 스레드를 확실히 사용할 수 있지만 주요 용도 중 하나는 사용자에게 친숙한 이유로 한 번에 둘 이상의 작업을 수행하는 것입니다.

예를 들어, 백그라운드에서 일부 처리를 수행해야하고 UI 입력에 계속 응답해야하는 경우 스레드를 사용할 수 있습니다. 스레드가 없으면 많은 처리를 시도 할 때마다 사용자 인터페이스가 중단됩니다.

이 관련 질문도 참조하십시오 : 스레드의 실제 사용


UI 처리는 IO 바운드 작업의 전형적인 예입니다. 처리와 IO 작업을 모두 수행하는 단일 CPU 코어를 갖는 것은 좋지 않습니다.
Donal Fellows

6

이상적인 숫자는 CPU 당 하나의 스레드라는 @kyoryu의 주장에 강력히 동의하지 않습니다.

이런 식으로 생각하십시오. 왜 다중 처리 운영 체제가 있습니까? 대부분의 컴퓨터 기록에서 거의 모든 컴퓨터에는 하나의 CPU가있었습니다. 그러나 1960 년대부터 모든 "실제"컴퓨터에는 다중 처리 (일명 다중 태스킹) 운영 체제가있었습니다.

여러 프로그램을 실행하여 하나는 실행할 수 있고 다른 프로그램은 IO와 같은 것으로 차단합니다.

NT 이전의 Windows 버전이 멀티 태스킹인지에 대한 인수를 따로 설정할 수 있습니다. 그 이후로 모든 실제 OS에는 멀티 태스킹이있었습니다. 일부는 사용자에게 노출시키지 않지만 어쨌든 핸드폰 라디오 청취, GPS 칩과 대화, 마우스 입력 수락 등과 같은 작업을 수행합니다.

스레드는 좀 더 효율적인 작업입니다. 작업, 프로세스 및 스레드간에 근본적인 차이는 없습니다.

CPU는 끔찍한 일이므로 끔찍한 일을 할 준비가되어 있어야합니다.

대부분의 절차 적 언어 인 C, C ++, Java 등에서는 적절한 스레드 안전 코드를 작성하는 것이 많은 작업이라는 데 동의합니다. 오늘날 시중에 6 개의 코어 CPU가 있고 멀지 않은 16 개의 코어 CPU가 있기 때문에 멀티 스레딩이 점점 더 중요한 요구 사항이기 때문에 사람들은 이러한 오래된 언어에서 벗어날 것으로 기대합니다.

@kyoryu와의 의견 차이는 IMHO 일 뿐이며 나머지는 사실입니다.


5
프로세서 바운드 스레드 가 많은 경우 이상적인 수는 CPU 당 1 개 (또는 1 개 이하)로 모든 I / O 및 OS를 관리하는 것입니다. IO 바운드 스레드 가 있다면 단일 CPU에 상당히 많은 스택을 쌓을 수 있습니다. 응용 프로그램마다 프로세서 바인딩 및 IO 바인딩 작업이 서로 다릅니다. 그것은 완전히 자연 스럽지만 보편적 선언에주의해야하는 이유입니다.
Donal Fellows

1
물론 스레드와 프로세스의 가장 중요한 차이점은 Windows에는 fork ()가 없기 때문에 프로세스 생성이 실제로 비싸서 스레드를 과도하게 사용한다는 것입니다.
ninjalj

단백질 폴딩, SETI 등을 제외하고는 매우 오랫동안 계산 된 실제 사용자 작업이 없습니다. 항상 사용자로부터 정보를 얻고 디스크와 대화하고 DBMS와 대화해야합니다. 예, fork ()의 ​​비용은 커틀러가 DEC의 다른 사람들과 NT를 저주 한 많은 것들 중 하나입니다.
fishtoprecords

5

임의의 수의 요청을 처리해야하는 웹 서버를 상상해보십시오. 그렇지 않으면 인터넷을 통해 응답을 보내는 것을 포함하여 다른 모든 요청이 완료 될 때까지 각각의 새 요청이 대기해야하기 때문에 요청을 병렬로 제공해야합니다. 이 경우 대부분의 웹 서버는 일반적으로 제공하는 요청 수보다 코어 수가 적습니다.

또한 서버 개발자가 더 쉽게 만들 수 있습니다. 요청을 처리하는 스레드 프로그램 만 작성하면되며 여러 요청 저장, 요청 순서 등을 생각할 필요가 없습니다.


2
스레딩을 지원하지만 멀티플렉싱 io를위한 용량이없는 운영 체제 용 소프트웨어를 작성하고 있습니까? 이 경우 멀티플렉싱 io가 코어보다 더 많은 스레드를 생성하는 것보다 거의 항상 효율적이기 때문에 웹 서버는 아마도 나쁜 예라고 생각합니다.
Jason Coco

3

많은 스레드가 잠 들어 사용자 입력, I / O 및 기타 이벤트를 기다립니다.


확실 해요 Windows에서 작업 관리자를 사용하거나 실제 OS에서 TOP을 사용하고 얼마나 많은 작업 / 프로세스가 필요한지 확인하십시오. 항상 90 % 이상입니다.
fishtoprecords

2

스레드는 UI 응용 프로그램의 응답 성을 도울 수 있습니다. 또한 스레드를 사용하여 코어에서 더 많은 작업을 수행 할 수 있습니다. 예를 들어, 단일 코어에서 하나의 스레드가 IO를 수행하고 다른 스레드가 일부 계산을 수행하도록 할 수 있습니다. 단일 스레드 인 경우 IO가 완료 될 때까지 코어가 유휴 상태 일 수 있습니다. 꽤 높은 수준의 예제이지만 스레드를 사용하면 CPU를 조금 더 세게 두드리는 데 확실히 사용할 수 있습니다.


보다 구체적으로, 하나의 스레드는 I / O를 대기 하고 다른 스레드 는 계산을 수행 할 수 있습니다 . I / O가 (중요한) CPU주기를 취했다면 별도의 스레드에서 실행하면 아무런 이점이 없습니다. 이점은 I / O 스레드가 엄지 알루미늄을 돌리면서 큰 알루미늄 실린더가 제자리에 고정되기를 기다리거나 패킷이 아이슬란드 등의 와이어를 통해 도착하기를 기다리는 동안 계산 스레드를 실행할 수 있다는 것입니다.
Ken

2

프로세서 또는 CPU는 시스템에 연결된 물리적 칩입니다. 프로세서는 여러 개의 코어를 가질 수 있습니다 (코어는 명령을 실행할 수있는 칩의 일부입니다). 코어는 여러 스레드를 동시에 실행할 수있는 경우 운영 체제에 여러 가상 프로세서로 나타날 수 있습니다 (스레드는 단일 명령 시퀀스 임).

프로세스는 응용 프로그램의 다른 이름입니다. 일반적으로 프로세스는 서로 독립적입니다. 한 프로세스가 종료되면 다른 프로세스도 종료되지 않습니다. 프로세스가 통신하거나 메모리 또는 I / O와 같은 리소스를 공유 할 수 있습니다.

각 프로세스에는 별도의 주소 공간과 스택이 있습니다. 프로세스는 여러 스레드를 포함 할 수 있으며 각 스레드는 동시에 명령을 실행할 수 있습니다. 프로세스의 모든 스레드는 동일한 주소 공간을 공유하지만 각 스레드에는 자체 스택이 있습니다.

이러한 정의와 이러한 기본 사항을 사용한 추가 연구를 통해 이해하는 데 도움이되기를 바랍니다.


2
이것이 어떻게 그의 질문을 다루는 지 모르겠습니다. 그의 질문에 대한 나의 해석은 코어의 스레드 사용 및 사용 가능한 자원의 최적 사용, 또는 스레드 수 또는 그 라인을 따라 증가하는 스레드의 동작에 관한 것입니다.
David

@David 아마도 내 질문에 대한 직접적인 대답은 아니지만 여전히 그것을 읽음으로써 배운 것 같습니다.
Nick Heiner 2016 년

1

스레드의 이상적인 사용법은 실제로 코어 당 하나씩입니다.

그러나 비동기 / 비 차단 IO를 독점적으로 사용하지 않으면 어느 시점에서 IO에서 스레드가 차단되어 CPU를 사용하지 않을 가능성이 높습니다.

또한 일반적인 프로그래밍 언어를 사용하면 CPU 당 1 개의 스레드를 사용하기가 다소 어렵습니다. 동시성 (예 : Erlang)을 중심으로 설계된 언어를 사용하면 추가 스레드를 더 쉽게 사용할 수 없습니다.


정기적 인 작업에 스레드를 사용하는 것은 매우 일반적이며 환영받는 워크 플로이며 코어를 훔친 경우 이상적이지 않습니다.
Nick Bastin 2018 년

@Nick Bastin : 그렇습니다. 그러나 이러한 작업을 작업 대기열에 넣고 해당 대기열 (또는 유사한 전략)에서 실행하는 것이 더 효율적입니다. 최적의 효율성을 위해 불필요한 컨텍스트 전환 및 추가 스택 할당으로 인한 오버 헤드를 방지하므로 코어 당 1 개의 스레드가 모든 것을 능가합니다. CPU가 실제로 코어 당 하나의 작업 (가능한 경우 하이퍼 스레딩과 같은 작업) 만 수행 할 수 있으므로 주기적 작업 '활성'상태 인 동안 코어를 훔쳐 야합니다 .
kyoryu

@Nick Bastin : 불행히도, 주요 답변에서 말했듯이, 대부분의 현대 언어는이를 효과적으로 수행하는 시스템을 쉽게 구현하는 데 쉽지 않습니다. 일반적으로 언어의 일반적인 사용법과 싸우는 결과가 발생합니다.
kyoryu

내 요점은 코어 당 하나의 스레드가 최적이 아니라는 것입니다. 코어 당 하나의 스레드가 파이프 꿈 (내장되어 있지 않은 한)이고 그것을 때리려 고 시도하는 것은 시간 낭비이므로 사용중인 스레드 수를 최적화하려고 시도하기보다는 쉬운 작업을 수행하십시오 (현대 스케줄러에서 덜 효율적이지 않음). 아무 이유없이 실을 회전시켜야합니까? 물론 컴퓨터 리소스를 불필요하게 낭비하는지 여부는 스레딩에 관계없이 문제가됩니다.
Nick Bastin

@Nick Bastin : 요약하자면 코어 당 하나의 스레드가 이상적이지만 실제로 달성하기는 쉽지 않습니다. 실제로 그러한 일을 달성 할 가능성에 대해 이야기 할 때 아마도 '어려운 것'보다 강했을 것입니다.
kyoryu

1

일부 API를 설계하는 방법은, 당신은하지 선택의 여지가 있지만 (차단 작업과 무엇이든)을 별도의 스레드에서 실행할 수 있습니다. 예를 들어 Python의 HTTP 라이브러리 (AFAIK)가 있습니다.

일반적으로 이것은 큰 문제는 아니지만 (문제가있는 경우 OS 또는 API는 대체 비동기 작동 모드와 함께 제공되어야합니다 :) select(2), 아마도 I / 대기 중 스레드가 잠들 것임을 의미하기 때문에 O 완료 뭔가 무거운 계산을하고있는 경우 반면에, 당신은 말보다 별도의 스레드에 넣어의 GUI 스레드 (당신은 수동 멀티플렉싱을 즐길 제외).


1

나는 이것이 좋은 대답이 많은 매우 오래된 질문이라는 것을 알고 있지만 현재 환경에서 중요한 것을 지적하려고 여기 있습니다.

멀티 스레딩을위한 응용 프로그램을 디자인하려는 경우 특정 하드웨어 설정을 디자인하지 않아야합니다. CPU 기술은 수년 동안 매우 빠르게 발전해 왔으며 코어 수는 꾸준히 증가하고 있습니다. 스레드가 4 개만 사용되도록 의도적으로 응용 프로그램을 설계하는 경우 잠재적으로 8 코어 시스템 (예를 들어)으로 제한됩니다. 이제는 20 코어 시스템도 시판되고 있으므로 이러한 디자인은 확실히 좋은 것보다 더 큰 피해를줍니다.


0

첫 번째 추측에 대한 응답으로, 멀티 코어 머신은 단일 프로세스의 여러 스레드뿐만 아니라 여러 프로세스를 동시에 실행할 수 있습니다.

첫 번째 질문에 대한 답변 : 여러 스레드의 요점은 일반적으로 하나의 응용 프로그램 내에서 여러 작업을 동시에 수행하는 것입니다. 인터넷상의 전형적인 예는 메일을 보내고받는 이메일 프로그램과 페이지 요청을 받고 보내는 웹 서버입니다. (Windows와 같은 시스템을 하나의 스레드 만 또는 하나의 프로세스 만 실행하도록 축소하는 것은 본질적으로 불가능합니다. Windows 작업 관리자를 실행하면 일반적으로 긴 활성 프로세스 목록이 표시되며,이 중 다수는 다중 스레드를 실행합니다. )

두 번째 질문에 대한 답변 : 대부분의 프로세스 / 스레드는 CPU 바운드가 아니며 (즉, 지속적으로 실행되고 중단되지 않음) 대신 I / O가 끝날 때까지 자주 중지하고 기다립니다. 대기 중에 다른 프로세스 / 스레드는 대기 코드에서 "스틸 링"없이 (단일 코어 시스템에서도) 실행될 수 있습니다.


-5

스레드는 일련의 작업처럼 간단하게 코드를 작성할 수있게하는 추상화로, 코드가 다른 코드와 인터레이스되어 실행되거나 IO를 기다리거나 다른 스레드의 대기를 대기하는 것을 알 수 있습니다. 이벤트 또는 메시지.


다운 보트 이후에 더 많은 예제를 추가하여 이것을 편집했을 수도 있지만 성능을 확장하기 위해 스레드 (또는 프로세스에서 거의 차이가 없음)가 개발되지 않았지만 비동기 코드를 단순화하고 복잡한 상태 머신을 작성하지 않도록했습니다. 프로그램에서 가능한 모든 슈퍼 상태를 처리해야했습니다. 실제로 대형 서버에서도 일반적으로 하나의 CPU가있었습니다. 왜 내 답변이 도움이되지 않는지 궁금합니다.
KarlP

-8

요점은 대다수의 프로그래머가 상태 머신을 설계하는 방법을 이해하지 못한다는 것입니다. 모든 것을 자체 스레드에 넣을 수 있기 때문에 프로그래머는 다른 진행중인 계산의 상태를 효율적으로 표현하는 방법에 대해 생각하지 않아도 중단되고 나중에 다시 시작할 수 있습니다.

예를 들어, CPU를 많이 사용하는 작업 인 비디오 압축을 고려하십시오. GUI 도구를 사용하는 경우 인터페이스가 응답 상태로 유지되기를 원할 것입니다 (진행률 표시, 요청 취소에 대한 응답, 창 크기 조정 등). 따라서 한 번에 큰 단위 (하나 이상의 프레임)를 처리하고 UI와 별도로 자체 스레드에서 실행하도록 인코더 소프트웨어를 설계합니다.

물론 진행중인 인코딩 상태를 저장하여 프로그램을 종료하여 리소스를 많이 사용하는 게임을 재부팅하거나 재생할 수 있다는 것을 알게되면 처음. 또는 OS에 대한 완전히 새로운 프로세스 동면 문제를 엔지니어링하기로 결정하여 개별 앱을 디스크에 일시 중지하고 다시 시작할 수 있습니다.


7
-1의 가치는 없지만 (이것은) 진지하게, 그것은 내가이 주제에 대해 내가 들었던 가장 멍청한 속임수입니다. 예를 들어 상태 머신을 구현하는 데 아무런 문제가 없습니다. 전혀. 다른 도구가있을 때 코드 보다 명확 하고 유지 관리하기 쉬운 도구를 사용하고 싶지 않습니다 . 상태 머신에는 자체 위치가 있으며 해당 위치에는 일치 할 수 없습니다. GUI 업데이트로 CPU를 많이 사용하는 인터레이스 작업은 그 중 하나가 아닙니다. 최소한 코 루틴이 더 나은 선택이며 스레딩이 훨씬 좋습니다.
저의 올바른 의견에 동의하십시오

내 대답을 수정하는 모든 사람에게 이것은 스레드 사용에 대한 논쟁이 아닙니다! 훌륭한 상태 머신을 코딩 할 수 있다면 필요하지 않더라도 별도의 스레드에서 상태 머신을 실행하는 것이 좋습니다. 필자는 종종 스레드를 사용하는 선택은 주로 다른 프로그래머가 아닌 "너무 어려운"것으로 간주되는 상태 머신의 설계를 피하려는 욕구에서 비롯되었다고 말했다.
R .. GitHub 중지 지원 얼음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.