멀티 코어 프로세서에서 스레드 할당을 프로그래밍하는 방법은 무엇입니까?


13

예를 들어, 두 개의 다른 프로세서 코어에서 실행되는 두 개의 다른 스레드를 사용하는 프로그램을 작성하기 위해 멀티 코어 프로세서에서 스레드를 실험하고 싶습니다.

그러나 스레드가 다른 코어에 할당되는 수준은 분명하지 않습니다. 운영 체제 및 프로그래밍 언어 구현에 따라 다음과 같은 시나리오를 상상할 수 있습니다.

  1. 스레드 할당은 운영 체제에서 관리합니다. 스레드는 OS 시스템 호출을 사용하여 생성되며 프로세스가 멀티 코어 프로세서에서 실행되는 경우 OS는 자동으로 다른 코어에 다른 스레드를 할당 / 예약하려고 시도합니다.
  2. 스레드 할당은 프로그래밍 언어 구현에 의해 관리됩니다. 스레드를 다른 코어에 할당하려면 특별한 시스템 호출이 필요하지만 프로그래밍 언어 표준 스레드 라이브러리는 해당 언어에 표준 스레드 구현을 사용할 때이를 자동으로 처리합니다.
  3. 스레드 할당은 명시 적으로 프로그래밍해야합니다. 내 프로그램에서 사용 가능한 코어 수를 감지하고 라이브러리 함수와 같은 다른 코어에 다른 스레드를 할당하기 위해 명시 적 코드를 작성해야합니다.

질문을보다 구체적으로 만들기 위해 Windows 또는 Linux에서 Java 또는 C ++로 멀티 스레드 응용 프로그램을 작성했다고 가정하십시오. 응용 프로그램이 멀티 코어 프로세서에서 실행될 때 여러 코어를 마술처럼보고 사용합니까 (모든 것이 운영 체제 또는 표준 스레드 라이브러리에 의해 관리되기 때문에) 또는 여러 코어를 인식하도록 코드를 수정해야합니까? ?

답변:


11

응용 프로그램이 멀티 코어 프로세서에서 실행될 때 여러 코어를 마술처럼보고 사용합니까 (모든 것이 운영 체제 또는 표준 스레드 라이브러리에 의해 관리되기 때문에) 또는 여러 코어를 인식하도록 코드를 수정해야합니까? ?

간단한 답변 : 예. 일반적으로 운영 체제 또는 스레딩 라이브러리에서 관리합니다.

운영 체제의 스레딩 하위 시스템은 우선 순위에 따라 스레드를 프로세서에 할당합니다 (옵션 1). 즉, 스레드가 시간 할당 또는 블록 실행을 완료하면 스케줄러는 다음으로 우선 순위가 높은 스레드를 찾아서이를 CPU에 할당합니다. 자세한 내용은 운영 체제마다 다릅니다.

즉, 옵션 2 (프로그래밍 언어로 관리) 및 3 (명시 적으로)이 존재합니다. 예를 들어, 최신 버전의 .Net에서 Tasks 라이브러리 및 async / await는 개발자에게 병렬화 가능 (즉, 자체적으로 동시에 실행될 수있는) 코드를 작성하는 훨씬 쉬운 방법을 제공합니다. 기능적 프로그래밍 언어는 본질적으로 병렬화 가능하며 일부 런타임은 가능한 경우 프로그램의 다른 부분을 병렬로 실행합니다.

옵션 3 (명시 적으로)과 관련하여 Windows에서는 스레드 선호도 (스레드를 실행할 수있는 프로세서 지정)를 설정할 수 있습니다. 그러나 이것은 응답 시간이 가장 빠른 시스템을 제외한 모든 시스템에서 일반적으로 필요하지 않습니다. 효과적인 스레드 대 프로세서 할당은 하드웨어에 매우 의존적이며 동시에 실행되는 다른 응용 프로그램에 매우 민감합니다.

실험을하려면 소수 목록 생성 또는 Mandelbrot 세트 생성과 같이 CPU를 많이 사용하는 장기 실행 작업을 생성하십시오. 이제 좋아하는 라이브러리에 두 개의 스레드를 작성하고 다중 프로세서 시스템에서 두 스레드를 실행하십시오 (즉, 지난 몇 년 동안 릴리스 된 모든 것). 두 작업은 동시에 실행되기 때문에 거의 동시에 완료되어야합니다.


설명해 주셔서 감사합니다 (+1). 내 테스트 프로그램은 병합 정렬 구현입니다. 분할 단계에서 사용 가능한 코어가있는 한 다른 스레드를 만들고 싶습니다. 예를 들어, 두 개의 코어를 사용하면 배열의 각 절반이 다른 스레드 / 코어로 정렬됩니다. 병합하는 동안 불필요한 스레드는 결합 / 종료됩니다.
Giorgio

데이터가 무작위로 분포 된 경우 이러한 방식으로 정렬하기가 어렵습니다. 예, 분리하여 다른 스레드에서 각 부분을 정렬 할 수 있지만 결국에는 모든 부분을 병합해야합니다. 스레드가 데이터 구조를 공유하는 경우 경합 또는 잠금 문제가 발생할 수도 있습니다. 정렬이 스레딩에서 이점을 얻을 수는 없지만 선형 성능 향상은 아닙니다.
akton

데이터가 공유되지 않으므로 어레이의 두 절반을 독립적으로 정렬 할 수 있습니다. 데이터를 포함하는 전체 배열 또는 목록을 조작하는 하나의 스레드로 첫 번째 분할 및 마지막 병합 만 수행하면됩니다. 이는 데이터의 한 번의 완전한 스캔을 병렬로 실행할 수 없음을 의미합니다. 나머지 모든 스캔은 가능합니다.
Giorgio

물론, 나는 또한 당신의 모범을 훌륭한 후보로 생각합니다. 나는 현재 병합 정렬에 더 익숙합니다 (그리고 병렬 버전이 아닌 버전을 구현했습니다). 첫 번째 시도로 병합 정렬이 더 적합 할 것입니다.
Giorgio

2
이 답변에는 좋은 운영 체제가 다른 CPU 또는 코어에서 작업 시간을 단기 기아와 비교하는 데 드는 비용의 균형을 맞추기에 충분히 똑똑하다는 점을 덧붙일 것입니다. 중요한 아키텍처에서 결과는 자동적 인 선호도와 유사합니다. OS는 모든 작업을 가능한 한 빨리 실행하도록 개발되었으며, 스레드를 코어에 묶고 그러한 결정을 내리는 능력을 약화시켜 발을 딛고있을 수 있습니다.
Blrfl

-1

한때 거대한 SGI IRIX 환경이있었습니다. 단지 그것을 위해, 나는 단지 작은 CPU 스레드를 소비하는 작은 멀티 스레드 자바 프로그램을 작성하고 그 안에 12 개의 스레드를 만들었습니다. 이 작업은 NUMA 아키텍처에서 12 개의 CPU로 확장되었습니다. 프로그램을 찾아서 Dell R910에서 실행하고 확인하십시오.


3
이 답변은 실제로 기존 답변에별로 도움이되지 않습니다. 아마도 SGI 시스템의 JVM이 스레드를 코어에 할당 한 이유를 자세히 설명했다면
Jay Elston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.