"멀티 코어"친화적이라고 주장하는 프로그램


17

일반적으로 멀티 코어 프로세서를 최대한 활용하도록 설계되지 않았다고 주장하는 프로그램을 언급하면서이 문구 또는 이와 유사한 문구가 종종 사용됩니다. 이것은 특히 비디오 게임 프로그래밍에서 일반적입니다. (물론 많은 프로그램은 동시성이 없으며 기본 스크립트 등과 같이 필요하지 않습니다).

어떻게 이럴 수있어? 많은 프로그램 (특히 게임)은 본질적으로 동시성을 사용하며, OS가 CPU에서 작업 예약을 담당하고 있기 때문에 이러한 프로그램은 본질적으로 사용 가능한 다중 코어를 활용하지 않습니까? 이러한 맥락에서 "여러 코어를 활용"한다는 것은 무엇을 의미합니까? 이 개발자들은 실제로 OS 작업 예약을 금지하고 선호도 또는 자체 예약을 강요합니까? (주요 안정성 문제와 같은 소리).

저는 Java 프로그래머이므로 추상화 또는 기타로 인해이 문제를 처리하지 않았을 수도 있습니다.


11
단일 프로세서 / 코어 시스템에서는 작동하지만 여러 프로세서 / 코어의 동시성은 깨지는 동기화에서 바로 가기가 사용되었을 가능성이 큽니다.
Bart van Ingen Schenau

@BartvanIngenSchenau : 맞습니다. 이를 확장하여 답변으로 게시해야합니다. 다른 모든 사람들이 그 요점을 놓쳤다 고 생각합니다.
kevin cline

1
@Bart가 정말 가깝다고 생각합니다. 그러나 s / work / 작동하는 것으로 보이며 마크에 더 가깝습니다.
벤 Voigt

제쳐두고-나는 프로그래머가 아닌 사용자로서 이것을 경험했습니다 .Windows XP의 Ground Control 2. 멀티 코어 시스템에서 제대로 작동하려면 코어 선호도를 하나의 코어에만 설정해야했습니다. 그렇지 않으면 모든 애니메이션 (실제로 전체 게임)이 10 배 속도로 실행됩니다. . 나는 게임에 대한 작업을하지 않았지만 내 생각에 게임의 일부는 동시에 특정 양의 작업을 수행하는 프로세서에만 의존하는 것처럼 보였습니다.
jammypeach

답변:


28

좋은 동시성에는 응용 프로그램에서 몇 개의 스레드를 던지고 최상의 결과를 기대하는 것보다 훨씬 많은 것이 필요합니다. 프로그램이 당혹스럽게 병렬 에서 순수 순차 로 진행되는 방법에는 여러 가지가 있습니다 . 주어진 프로그램은 Amdahl의 법칙 을 사용 하여 문제 나 알고리즘의 확장 성을 표현할 수 있습니다 . 당황스럽게 병렬 응용 프로그램에 대한 몇 가지 자격은 다음과 같습니다.

  • 공유 상태 없음, 모든 기능은 전달 된 매개 변수에만 의존
  • 물리적 장치 (그래픽 카드, 하드 드라이브 등)에 액세스 할 수 없음

다른 자격이 있지만이 두 가지만으로 특히 게임이 여러 코어를 활용한다고 생각하는 것만 큼 쉽지 않은 이유를 이해할 수 있습니다. 우선, 다른 기능이 물리, 운동을 계산하고 인공 지능을 적용하는 등 다양한 기능으로 렌더링 될 월드 모델을 공유해야합니다. 둘째,이 게임 모델의 각 프레임은 그래픽 카드로 화면에 렌더링되어야합니다.

공평하게 말하면, 많은 게임 제작자들은 타사에서 생산 한 게임 엔진을 사용합니다. 시간이 걸렸지 만이 타사 게임 엔진은 이제 예전보다 훨씬 더 평행합니다.

효과적인 동시성을 처리하는 데 더 큰 아키텍처 문제가 있습니다

동시성은 백그라운드에서 작업을 실행하는 것부터 동시성을위한 완전한 아키텍처 지원에 이르기까지 다양한 형태를 취할 수 있습니다. 일부 언어는 다음과 같은 매우 강력한 동시성 기능을 제공합니다. ERLANG 하지만 애플리케이션을 구성하는 방법에 대해 매우 다르게 생각해야합니다.

모든 프로그램이 완전한 멀티 코어 지원의 복잡성을 필요로하는 것은 아닙니다. 이러한 예 중 하나는 세금 소프트웨어 또는 모든 양식 중심 응용 프로그램입니다. 대부분의 시간이 사용자의 작업 수행을 기다리는 데 멀티 스레드 응용 프로그램의 복잡성은 그다지 유용하지 않습니다.

일부 응용 프로그램은 웹 응용 프로그램과 같이 훨씬 난해한 병렬 솔루션에 적합합니다. 이 경우 플랫폼은 당황스럽게 병렬로 시작되며 스레드 경합을 강요하지 않아도됩니다.

결론:

여러 스레드 (따라서 코어)를 사용하지 않아 모든 응용 프로그램이 실제로 손상되는 것은 아닙니다. 그로 인해 상처를 입는 사람들에게는 때로는 계산이 병렬 처리에 익숙하지 않거나 조정하기위한 오버 헤드가 응용 프로그램을보다 취약하게 만듭니다. 불행히도, 병렬 처리는 여전히 잘해야 할만 큼 쉽지 않습니다.


이것은 훌륭한 분석입니다. 나에게 버그가되는 한 가지 사실은 실제 프로그램이 종종 당황스럽지 않고 병렬화하기가 어렵다는 요점입니다 . 동일한 작업을 병렬 로 수행하는 것이 불가능할 수도 있지만 다른 작업을 병렬 로 수행 하는 것은 매우 쉽습니다 ( 파이프 라인 아키텍처 또는 별도의 UI 스레드).
amon

8
실제 요점은 병렬 실행을 위해 설계해야하며, 그렇지 않은 경우 설계 부족으로 인해 제약을 받는다는 것입니다. 나는 동의 할 수 있지만이 높은 사용자의 기대와 기존 응용 프로그램의 경우, 병렬로 다른 일을 매우 간단합니다. 이 경우 가능하면 다시 작성해야 할 수도 있습니다. 재 작성은 본질적으로 위험하지만 때로는 좋은 주장을 할 수 있습니다. 가능한 한 많은 코드를 유지하면서 병렬 처리를 최대화하는 몇 가지 재 작성을 수행했습니다. 숨겨진 요소 가 많이 있습니다 .
Berin Loritsch

좋은 대답입니다. 일부 시스템을 병렬화하면 수익이 감소 할뿐만 아니라 일부 시스템은 병렬화에 필요한 오버 헤드로 인해 속도느려질 수 있음을 강조하는 것이 좋습니다. 특히, 많은 세마포어 / 잠금 및 컨텍스트 전환은 런타임에 부정적인 영향을 줄 수 있습니다. 상황에 맞는 전환은 특히 캐시의 효율성을 떨어 뜨릴 수 있습니다. 이는 시스템 최적화 시점에있어 중요한 문제입니다. 특히 OP의 게임 엔진 예제를 통해 병렬 액세스보다 캐싱 최적화에 대해 훨씬 더 많이들을 수 있습니다.
Gankro

35

많은 프로그램 (특히 게임)은 본질적으로 동시성을 사용합니다.

아니요, 실제로는 반대입니다. 대부분의 앱은 단일 스레드 사고 방식으로 작성되며 개발자는 동시성을 지원하기 위해 필요한 변경을하지 않았습니다.

C, C ++ 및 C #에서는 애플리케이션에 새 스레드 및 / 또는 프로세스를 시작하도록 명시 적으로 지시해야합니다.

스레드 스케줄링에 너무 집중하고 잠재적 스레드 내의 데이터 처리에 충분하지 않다고 생각합니다. 스레드 및 / 또는 프로세스에서 데이터를 공유하려면 동기화 형식이 필요합니다. 여러 스레드를 사용하도록 응용 프로그램을 변경했지만 동기화가 제대로 이루어지지 않으면 코드에서 버그를 추적하기가 어려울 것입니다.

내가 작업 한 멀티 스레드 응용 프로그램의 경우 일반적으로 디스패치에 대해 걱정하지 않고 데이터 동기화에 대해서만 걱정하지 않았습니다. 디스패치에 대해 걱정해야 할 유일한 시간은 잘못된 데이터 동기화로 인해 경쟁 조건을 추적 할 때였습니다.

일반적으로 응용 프로그램에서 여러 코어를 사용할 수 없다고하면 데이터 조작을 보호하기 위해 동기화가 이루어지지 않은 것입니다.


이는 대규모 개발자 / 출판 업체의 새로운 최신 프로그램에서도 마찬가지입니다. 앉아서 프로그램을 작성할 때 디자인 단계에서 가장 먼저 생각하는 것 중 하나는 동시성이 필요합니까? 디자인이 크게 다를 수 있기 때문입니다. 특히 게임은 어느 정도의 동시성을 가져야합니다. 그렇지 않으면 수천 개의 온 스크린 모델 중 하나가 무언가를 시도했을 때 게임이 정지됩니다.
SnakeDoc

5
@SnakeDoc-도메인을 혼동하는 것 같습니다. Big Game 회사는 가장 확실하게 동시성을 사용하여 작성하지만 동시성이 지원되지 않는 Big Game 공동의 게임을 아직 보지 못했습니다. 필자가 동시성을 지원할 수없는 앱과 게임은 일반적으로 소규모 사고를 시작하지 않았던 소규모 상점 / 개인 개발자가 만든 것입니다. 그리고 응용 프로그램의 진화의 어느 시점에서, 사실 후에 동시성을 강화하는 것은 불가능합니다. 그리고 일부 앱은 동시성을 정당화하기에 충분하지 않았습니다.

또한 일부 게임은 게임 엔진 (코드 구현)을 업데이트하지 않고도 새로운 콘텐츠 (그래픽 및 게임 플레이)를 통해 번창합니다. 따라서 게임 엔진은 기술면에서 수년이 걸릴 수 있습니다.
rwong

6
@SnakeDoc : 수천 개의 온 스크린 모델을 처리하기 위해 동시성이 필요하지 않습니다. 게임의 모든 오브젝트가 시뮬레이션하기 위해 자체 스레드를 필요로하는 것은 아닙니다. 하나의 스레드는 모든 시간 단계에서 화면의 모든 업데이트를 처리 할 수 ​​있습니다.
user2357112는 Monica

13

이것은 다중 스레드에 관한 것만 큼 다중 코어에 관한 것이 아닙니다. OS는 원하는 코어에서 스레드가 실행되도록 예약 할 수 있으며이 예약은 예약중인 프로그램에 투명합니다. 그러나 많은 프로그램은 여러 스레드를 사용하여 작성되지 않으므로 한 번에 하나의 코어에서만 실행할 수 있습니다.

단일 스레드 프로그램을 작성하는 이유는 무엇입니까? 그것들은 작성하기 쉽고 디버깅하기 쉽습니다 : 한 번에 여러 가지 일이 일어나고 서로 다른 방식으로 일어날 수있는 것이 아니라 한 번에 하나씩 발생합니다. 또는 프로그램이 멀티 코어 머신을 대상으로하지 않을 수 있습니다 (오래된 게임의 경우와 동일). 경우에 따라 컨텍스트 전환 및 스레드 간 통신의 오버 헤드가 병렬 실행으로 얻은 속도를 초과하면 (멀티 스레드 프로그램은 단일 스레드 버전보다 느리게 실행될 수도 있습니다 (프로그램의 일부는 병렬화 할 수 없음).


8

이것은 완전한 답변이 아닙니다. 조심스러운 이야기입니다.

어느 날 나는 동시 프로그래밍 과정의 학생들에게 병렬 퀵 정렬을 보여줄 것이라고 생각했습니다. Quicksort는 병렬화가 잘되어야한다고 생각했습니다. 나는 두 개의 실을 사용했습니다. 단일 코어 컴퓨터에서 실행하십시오. 결과는 다음과 같습니다.

  • 단일 스레드 버전의 경우 14 초
  • 2- 스레드 버전의 경우 15 초

이것은 내가 기대했던 것에 관한 것입니다.

그런 다음 새로운 듀얼 코어 시스템에서 시도했습니다.

  • 단일 스레드 버전의 경우 11 초
  • 2- 스레드 버전의 경우 20 초

두 스레드는 나머지 작업 대기열을 공유했습니다. 대기열 객체의 필드가 한 코어의 캐시와 다른 코어의 캐시 사이에서 뒤섞인 것처럼 보입니다.


2
몇 개의 배열 요소로 테스트 했습니까? 멀티 코어 프로그래밍이 캐시 라인 충돌을 피하기 위해 데이터를 복사해야했기 때문에 mergesort가 더 적합할까요?
rwong

2
@rwong 10,000,000 개의 배열 요소가있었습니다. 확실히 병합 정렬은 병렬화 될 것입니다. 병합 정렬을 사용했다면 아마도 유용한 교훈을 배우지 않았을 것입니다.
Theodore Norvell

1
@ArlaudPierre 알고리즘을 병렬화하는 것을 고려할 것입니다. 퀵소트는 흥미있는 작업 방식을 사용할 수 있으므로 흥미 롭습니다. 과제가 독립적이기 때문에 직관은 그것이 병렬 처리를 난처하게하는 모범이되어야한다는 것이 었습니다. 약간의 튜닝 후에 실제로 2에 가까운 속도를 얻었습니다.
Theodore Norvell

1
@Jules 정답은로드 밸런싱입니다. 또한 스레드 수를 쉽게 변경할 수있는 방식으로 작성하고 싶었습니다. 귀하의 접근 방식은 2의 거듭 제곱으로 훌륭하게 일반화되지만 다른 수의 스레드에는 잘 맞지 않습니다.
Theodore Norvell

2
@MaciejPiechotka 도덕은 당신이 제안하는 모든 것입니다. 그러나 OP로 돌아와서, 가장 관련있는 도덕은 멀티 스레드 프로그램이 달리 보장하기 위해 노력을 기울이지 않으면 단일 코어 프로세서보다 멀티 코어 아키텍처에서 실제로 느리게 실행될 수 있다는 것입니다.
Theodore Norvell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.