2013-05-09 3 views
1

두 개의 간단한 루프를 작성했습니다.Parrallel.For 루프가보다 느리게 실행됩니다

sw.Restart(); 
      Parallel.For(0,1000000,i => 
        { 
         Console.WriteLine(i); 
        });    

      sw.Stop(); 
      Console.WriteLine(sw.Elapsed); 

불행하게도, 그것은 첫째을 위해 53 초 정도 걸립니다 :

Stopwatch sw = Stopwatch.StartNew(); 

      for (int i = 0; i < 1000000; i++) 
      { 
       Console.WriteLine(i); 
      } 
      sw.Stop(); 
      Console.WriteLine(sw.Elapsed); 
      Console.ReadKey(); 

두 번째로 빠른 것으로 가정 Parrallel.For을 사용하고 있습니다 :

하나 '에 대한'표준을 사용하고 실행하고 약 1 분 50 초 두 번째로 (!!!).

왜 내가 잘못 했습니까?

+4

을 콘솔에 쓰려면 스레드가 동기화되어야하기 때문에? 대신 실제 작업을 해보십시오. – GSerg

+0

처음에는 콘솔에 쓰기 작업 대신 db 쓰기 작업이 있었지만 느린 작업을 수행했습니다. – ohadinho

+3

글쎄, db는 잠금/동기화를 발생시키는 공유 리소스이기도합니다. 이점을 얻으려면 병렬 코드에서 이러한 자원을 피하십시오. – GSerg

답변

0

난 당신이 데이터베이스 또는 당신이 가지고 콘솔 출력과 같은 I/O 리소스에 액세스하려고 할 때이 Parallel.For

를 사용하여 문에 대한 12.5 초를 사용하여 9 초를 가지고 linqpad에 코드를 시도 잠금 메커니즘을 사용하여 스레드를 동기화하십시오. 어쨌든 삽입이나 select 문에 대해 데이터베이스에 병렬로 액세스하는 것을 권장하지 않습니다.

그러나이 변화에 코드를 시도 :

Stopwatch sw = Stopwatch.StartNew(); 
StringBuilder str = new StringBuilder(); 

for (int i = 0; i < 1000000; i++) 
{ 
     str.AppendLine(i.ToString()); 
} 

sw.Stop(); 
Console.WriteLine(sw.Elapsed); 

str = new StringBuilder(); 
sw.Restart(); 

Parallel.For(0,1000000,i => 
       { 
        str.AppendLine(i.ToString()); 
       });    

sw.Stop(); 
Console.WriteLine(sw.Elapsed); 

밀리 세컨드 백 몇 시간을 떨어질 것이다.

4

Parallel.For은 더 빨리 루프를 생성하지 않아야합니다. iterations가 병렬로 실행되도록되어 있습니다.

시도에서 루프를 병렬 처리하여 속도 향상과 일치하지 않는 리소스를 사용하는 코드를 사용했습니다 (충분한 대역폭이 없기 때문에 동기화가 필요한 것일 수도 있습니다). 따라서, 당신은 단지 그들을 따라 잡을 수없는 자원에 대한 스레드 경연 대회가 있습니다. 시나리오는 단순히 병렬 처리를 요구하지 않습니다 (적어도 사용자가 시도하는 방식은 아닙니다).

Parallel.For이 루프의 성능을 어떻게 향상시킬 수 있는지 알고 싶다면 결과를 배열의 독점 (각 반복마다) 색인에 저장하는 루프 내에서 계산을 수행하고 해당 계산을 확인하십시오 어떤 방식 으로든 다른 반복 결과에 의존하지 마십시오.

1

병렬 프로그래밍을 사용하면 더 많은 작업을 동시에 수행 할 수 있습니다. 이로 인해 코드가 병렬로 실행됩니다. 병렬 프로그래밍을 처음 보게되면 속도가 선형 적으로 증가 할 것으로 예상됩니다. 4 개의 코어가 4 배 빠릅니다.

그러나 이것은 병렬 프로그래밍에 가장 이상적인 코드가있는 경우에만 발생합니다. 아주 적은 알고리즘이 이것을 가지고 있습니다.

코드의 전체 속도는 병렬 처리 할 수없는 코드 부분에 의해 제한됩니다. Console.WriteLine 또는 Database 액세스에 대해 주석과 응답에 앞서 언급 한 것처럼 스레드가 동기화되어야합니다. 따라서이 부분은 병렬화 될 수 없습니다. 매우 큰 부분을 병렬로 실행할 수없는 코드가있는 경우 코드는 일반 루프보다 느리게 실행될 수도 있습니다. (스레드를 동기화하는 데 사용 된 시간).

Amdhal의 법칙은 우리에게이 결론을 제공합니다.

이 상태가

여기 Amdhal의 법칙에 대해 자세히 읽어 병렬화에서 사용할 수있는 전반적인 속도 향상이 제한됩니다 병렬화 할 수없는 프로그램의 작은 부분 :

http://en.wikipedia.org/wiki/Parallel_computing

관련 문제