Recent Post

Recent Comment

Archive

2020. 8. 3. 23:55 C#
Parallel.For()
Type Method
Namespace System.Threading.Tasks


Parallel.For() 메서드를 사용하여 루프를 병렬 처리화할 수 있다.

 

간단한 사용법은 아래와 같다. (편의를 위해 람다식을 주로 사용한다.)

Parallel.For(0, 10, i => A

{

    Console.WriteLine(i.ToString());

});

 

위 코드에서 루프 변수 i는 0부터 9까지 증가한다. 하지만 내부적으로 병렬 처리되기 때문에 0부터 9까지 '순서대로' 출력되는 것을 보장하지는 않는다. 이는 Parallel.For 메서드에서 루프를 부분 부분 쪼개어 각 cpu 코어의 상태에 따라 작업을 분배하여 처리하기 때문이다.

 

따라서 콘솔 창에는 0부터 9까지의 정수가 각각 단 한 번씩 출력되나, 순서대로 출력되는 것을 보장하지는 않는다.

 

반드시 정해진 순서대로 수행되어야 하는 루프를 대체하기에는 적합하지 않다. (ex : 배열을 순서대로 출력할 때)

각 루프가 서로 독립적인 상황에서 처리를 보다 빠르게 수행하기 위해서 사용하면 좋다. (ex : 배열의 모든 요소를 더할 때)

 

 

Parallel.For() 메서드에서 증감식을 사용하고 싶을 때!

Parallel.For() 메서드는 루프 변수를 int fromInclusive부터 int toExclusive까지 1씩 증가시키면서 수행하게 된다.

하지만 루프 변수를 2씩 증가시키고 싶을 수도 있고 때로는 2배씩 증가시켜야 할 때도 있다. 이럴 때는 Parallel.For()를 사용할 수 없나?

꼭 그렇지는 않다. 람다식을 사용하지 않고 일반 메서드 혹은 무명 메서드를 사용한다면 증감식을 표현할 수는 있다. 하지만 귀찮고 불편하다. 대신 Parallel.ForEach() 메서드와 Enumerable.Range를 사용하여 조금 편하게 증감식을 구현할 수 있다.

 

var range = Enumerable.Range(0, 100).Select(i => i * 2);

Parallel.ForEach(range, i =>

{

    Console.WriteLine(i.ToString());

});

 

위 코드는 먼저 Enumerable.Range(0, 100)의 요소들(0, 1, 2, ..., 99)을 순서대로 가져와서 Select(i => i * 2)의 i에 대입한 결과들의 집합(0, 2, 4, 6, ..., 198)을 Range로 생성한다.

IEnumerable<int> Enumerable.Range(int start, int count)

그 다음 생성된 Range를 Parallel.ForEach() 메서드의 range로 사용한다.

Parallel.ForEach() 메서드의 첫 번째 인자는 IEnumerable<TSource> 형식 즉, 요소들의 열거가 가능한 자료 구조가 올 수 있다. 이를테면 제네릭 List<T> 클래스는 IEnumerable<T> 인터페이스를 구현하기 때문에 List<T> 클래스의 인스턴스는 Parallel.ForEach() 메서드의 첫 번째 인자로 올 수 있다.

'C#' 카테고리의 다른 글

Test  (0) 2022.05.10
사용자 정의 형변환 (implicit, explicit)  (0) 2020.08.06
ArrayList  (0) 2020.08.03
posted by Dv Jm