2012-11-24 5 views
7

F #에서 TPL (Task Parallel Library)을 사용하여 많은 (> 1000) 장기 실행 작업을 실행하려고합니다. 다음은 현재 코드입니다.TPL 실행 시간이 긴 Parallel.For

시작하면 .NET에서 모든 작업을 한 번에 시작하고 그 사이를 끊임없이 반송합니다. 더 나은 것은 그것이 다음 과제로 이동하기 전에 완료 될 때까지 과제에 머물렀다면입니다. 이렇게하면 컨텍스트 전환이 최소화됩니다.

스케줄러에 힌트를 제공 할 수있는 방법이 있습니까? 힌트를 제공하는 것이 가능하지만 명확한 예제를 찾을 수 없거나 스케줄러가 이미 이것에 대해 현명하다는 것을 알고 있으며 너무 많은 컨텍스트 스위치가 발생했다는 사실을 알고 있습니다. 도와 주셔서 감사합니다!

답변

8

우리는 F # 대신 C#을 사용하여 비슷한 문제가 있었지만 라이브러리는 동일합니다. 이 솔루션은 병렬 처리 수준 제한했다 :

ParallelOptions parallelOptions = new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism = 16; 
Parallel.For(0, n, parallelOptions, i => { 
    . . . 
}); 

16

우리의 작업을 위해 잘 작동을 - 당신은 당신의 경우에 더 나은 어떤 값을 참조하는 실험을한다.

+0

+1, 초보다 빠릅니다. –

+0

MaxDegreeOfParallelism은 컴퓨터의 코어 수에 따라 다릅니 까? –

+0

@Wallhood : 작업이 CPU 바운드 인 경우 가능성이 높습니다. 작업이 IO 바인딩 (파일 처리, DB 액세스) 일 가능성이 높습니다. 일반적인 상황에서 가치가 2/4 코어에서 제대로 작동하는 경우, 더 정교한 것을 시도 할 실제 이유가 없었습니다. 예를 들어 16 코어 수퍼 머신에서 실행될 가능성이있는 프로그램이 아닙니다. – MiMo

5

내 경험에 비추어 볼 때 많은 수의 작업에서는 에 선형으로 MaxDegreeOfParallelism을 바인딩하는 것이 좋습니다. 당신이 F 번호에 병렬 프로그래밍 작업을하고 있기 때문에

let options = ParallelOptions() 
options.MaxDegreeOfParallelism <- Environment.ProcessorCount * 2 

Parallel.For(0, n, options, 
      (fun i -> (* Long running task here *))) |> ignore 

, 우수한 책 "Parallel Programming with Microsoft .NET", 특히 장에서 봐 주시기 바랍니다 : 여기에

는 F 번호 구문 미모의 하나가 @ 유사한 코드 조각입니다 "Parallel Loops"에 있습니다. @ 토마스는 샘플을 F #으로 번역했고 그들은 here입니다. 이것은 Environment.ProcessorCount로 평가 기본 작업 스케줄러 및 기본 ParallelOptions으로, 지금까지 내가 말할 수있는

// initialize ranges with passed in loop arguments and expected number of workers 
int numExpectedWorkers = (parallelOptions.EffectiveMaxConcurrencyLevel == -1) ? 
    Environment.ProcessorCount : 
    parallelOptions.EffectiveMaxConcurrencyLevel; 

:

1

는 참조 소스를 보면, 그것은 다음의 코드 조각은 근로자의 수를 결정 나타납니다 그래서 당신 자신이 프로세서 수에 MaxDegreeOfParallelism을 지정함으로써 다른 행동을 취하는 것은 이상합니다. 난 당신이 실제로 차이가 있는지 확인하기 위해 디버그하는 것이 좋습니다 (당신은 Thread.ManagedThreadId 장기 실행 작업 내에서 인쇄 할 수 있습니다).

+0

상당한 차이가있었습니다. 최대 동시성을 지정할 때 코어 당 한 번에 하나의 작업 만 열립니다. 지정하지 않으면 모든 작업이 한 번에 열립니다.한 번에 하나씩 만 작업했을 수도 있지만 모두 열어 놓았습니다. 나는 각 작업에 대한 타이머를 시작한다는 사실로부터 이것을 추론하고 있습니다. 병렬 처리를 지정할 때 각 작업의 시간은 동일했습니다. 내가 그 작업을 완료하지 못하면 완료하는 데 오랜 시간이 걸릴 수 있습니다. 밑에 무슨 일이 일어나고 있는지, 나는 모르지만 그건 내 관찰이었다. –

+0

아마도 작업자 수와 MaxDegreeOfParallelism은 서로 다른 두 가지일까요? 나는 @Wallhood가 말한 것을 확인한다. 우리가 1000 년의 작업을 할 때 'MaxDegreeOfParallelism'을 설정하지 않고 모두 병렬로 시작했고 기계를 꽉 쥐고 있었고, 문제는 16으로 고정되었다. (우리의 작업은 CPU가 아니지만 대부분 데이터베이스에 묶여있다) – MiMo