방프리
24.03.23 Chapter4. 병렬 처리 (Item 35) 본문
Item 35 : PLINQ가 병렬 알고리즘을 구현하는 방법을 이해하라
PLINQ를 사용하면 병렬로 처리하기 때문에 속도가 향상되지만 무조건적으로는 아니다. 어느 정도 계산을 분배한 뒤 동작하는 방식인데 제대로 사용하지 않으면 분할에 오히려 작업 속도가 더 많이 소요되어 PLINQ를 사용하지 않은 것보다 더 오래 걸릴 수 있다. PLINQ를 분할하는 방식은 아래 중 하나를 채용한다.
- 범위 분할
- 덩어리 분할
- 줄 단위 분할
- 해시 분할
1. 범위분할
가장 단순한 알고리즘으로 동작한다. 입력값의 범위를 태스크 수로 나누고, 나눈 집합을 각 태스크에 할당한다. 대신 분할하는 작업 때문에 배열형태인 IList<T> 형태만 지원한다.
2. 덩어리 분할
대스크가 추가 작업을 요구할 때마다 청크를 할당하는 방식. 작은 청크 크기에서부터 시작하여 점차 늘려가는 방식
쿼리가 소비되는 시간과 where절에 의해서 제외되는 요소 수에 따라 결정
3. 줄 단위 분할
범위 분할의 특수한 형태로 시퀸스에서 첫 번째 요소를 찾아내는 처리하는 방법을 최적화
예로 작업이 1 ~ 10이 있다면 1~5까지는 첫 번째 태스크 6~10까지는 두 번째 태스크가 처리
4. 해시 분할
Join,GroupJoin, GroupBy, Distinct, Except, Union, Intersect에 최적화된 알고리즘
PLINQ는 태스크의 병렬화를 위해 3개의 알고리즘을 사용하는데 다음과 같다.
- 파이프라이닝
- 스톱앤고
- 역열거형
1. 파이프 라이닝
하나의 스레드가 순회 과정(foreach 블록이나 쿼리 시퀸스)을 처리한다. 각 요소에 대한 쿼리 수행은 여러 스레드를 사용, 해당 시퀸스에 새로운 요청이 들어오면 다른 스레드가 처리한다.
2. 스톱앤고
순회를 시작한 스레드가 쿼리 표현식을 수행하는 나머지 스레드와 Join한다. ToList() 혹은 ToArray()를 사용해서 쿼리 결과를 즉각 반환해야 할 경우 사용. 또는 정렬 연산처럼 작업을 이어나가기 전에 전체 결과가 필요할 때 사용
단점으로는 메모리 사용량에 비해 속도는 조금밖에 개선되지 않는 경우가 종종 발생한다.
var stopAndGoArray = (from n in data.AsParallel()
where n < 150
select Factorial(n)).ToArray();
var stopAndGoList = (from n in data.AsParallel()
where n < 150
select Factorial(n)).ToList());
3. 역열거형
결과를 생성하지 않고 모든 쿼리식의 결과에 다른 액션을 취하는 경우 사용
var num = from n in data.AsParallel()
where n < 150
select Factorial(n);
num.ForAll(item => Console.WriteLine(item));
스탑앤고 방식보다 메모리를 적게 사용하면서 결과에 대해 뱅렬 액션을 수행할 수 있다.
모든 LINQ 쿼리는 지연방식이다. 쿼리를 미리 만들어 두되, 결과 요청 시 그 때 실행되는 방식. LINQ to Objects는 한 단계 더 나아가 사용자가 항모을 요청하면 그 항목에 대해서만 쿼리를 실행. PLINQ는 LINQ to SQL 혹은 Entity Framework와 비슷하게 첫 번째 항목을 요청하면 전체 시퀸스에 대한 결과를 생성.
병렬 알고리즘을 암달의 법칙 (최대한 병렬화를 시켜도 일정 성능 이상부터는 향상되지 않음)을 따른다. 즉, 얼마나 어떤 방식으로 처리되느냐에 따라 속도 및 최적화가 달라진다. 사용하더라도 내부 동작 방식에 대해 좀 더 연구하고 사용하자.
'C# > More Effective C#' 카테고리의 다른 글
24.04.07 Chapter4. 병렬 처리 (Item 37) (0) | 2024.04.07 |
---|---|
24.04.03 Chapter4. 병렬 처리 (Item 36) (0) | 2024.04.03 |
24.03.12 Chapter3. 태스크 기반 비동기 프로그래밍 (Item 34) (0) | 2024.03.12 |
24.03.11 Chapter3. 태스크 기반 비동기 프로그래밍 (Item 33) (0) | 2024.03.11 |
24.03.10 Chapter3. 태스크 기반 비동기 프로그래밍 (Item 32) (0) | 2024.03.10 |