Parallel Programming (PLINQ Optimizing and Parallel Class)

2022. 2. 18. 00:00CSharp/Advance

반응형

PLINQ Optimizing

 

output side optimization

아래와 같은 단순 작업은  PLINQ 의 ForAll 을 통해 성능을 향상 할 수 있다. 

foreach (int n in parallelQuery)
  DoSomething (n);
  
 parallelQuery.ForAll(....);

참조 : http://www.albahari.com/threading/part5.aspx#_Optimizing_PLINQ

 

input side optimization

 

Chunk partitioning : performace Average

Range partitioning : performace Poor to excellent

Hash partitioning   : performace Poor

 

GroupBy, Join, GroupJoin, Intersect, except, Union 및 Distinct 등은 요소를 비교해야 하며 선택의 여지 없다.

PLINQ 는 위에 같은 구문에 관하여 항상 Hash partitioning  을 사용한다.

Hash partitioning 은 모든 해시코드를 미리 계산해야 하기때문에 상대적으로 비효율적이다.

너무 느리다면 AsSequential 을 호출하여 병렬화를 비활성화 시키자.

이외에 모든 쿼리 연산자는 범위 분할을 사용 할지 청크 분할을 사용할지 선택가능하다.

범위 분할모든 요소가 처리하는 데 비슷한 양의 CPU 시간이 걸리는 긴 시퀀스에서 더 빠르다.

그렇지 않으면 일반적으로 청크 분할이 더 빠르다.

var numbers = Enumerable.Range(1, 10000000).ToArray();
Stopwatch stopwatch = Stopwatch.StartNew();
var parallelQuery = Partitioner.Create(numbers, true).AsParallel();
var sum = parallelQuery.Sum(i => Math.Sqrt(i));
stopwatch.Stop();
Console.WriteLine("Chunk elapsed = " + stopwatch.Elapsed.Ticks);

stopwatch.Restart();
var sum2 = ParallelEnumerable.Range(1, 10000000).Sum(i => Math.Sqrt(i));
stopwatch.Stop();
Console.WriteLine("Range elapsed = " + stopwatch.Elapsed.Ticks);

//output
/*
 * Chunk elapsed = 1183971
 * Range elapsed = 270483
 */

Parallel Class

Parallel.Invoke

: Action 대리자 배열을 병렬로 실행한 다음 완료될 때까지 기다림

Parallel.Invoke(
 async () => {
     var data = await new HttpClient().GetStringAsync("http://www.gutenberg.org/cache/epub/16452/pg16452.txt");
     Console.WriteLine("Downloaded pg16452.txt");
     },
 async () =>
 {
     var data = await new HttpClient().GetStringAsync("http://www.gutenberg.org/files/54700/54700-0.txt");
     Console.WriteLine("Downloaded 54700-0.txt");
 }
 );

Console.ReadLine();
// output
Downloaded 54700-0.txt
Downloaded pg16452.txt

Parallel.For

: for 와 같지만 병렬로 실행되며 순차적이지 않습니다. 

Parallel.For(0, 100, i => Console.Write($"{i} "));
// output
16 0 1 2 3 4 5 6 7 9 10 11 12 13 14 15

 

Paralle.Foreach

: foreach 와 같지만 병렬로 실행되며 순차적이지 않습니다. 

var numbers = Enumerable.Range(1, 100);
Parallel.ForEach(numbers, i => Console.Write($"{i} "));
//output
13 2 15 7 17 18 6 4 22 23 ...

 

관련영상

https://youtu.be/SnKmRHRqN2s

 

 

반응형

'CSharp > Advance' 카테고리의 다른 글

Builder  (0) 2022.02.22
Abstract Factory  (0) 2022.02.21
Parallel Programming (PLINQ)  (0) 2022.02.17
Parallel Programming (TPL Dataflow)  (0) 2022.02.16
Parallel Programming (TPL)  (0) 2022.02.15