[C#] C# 코딩공부 #2 병렬 프로그래밍

개발Velog·2020년 1월 7일
1

C#

목록 보기
2/9

병렬 프로그래밍(Parallel Programming)

CPU가 하나인 세대에서 현재는 듀얼코어 쿼드코어등이 보편화 되는 세대가 됨에 따라 CPU를 충분히 활용하기 위한 프로그래밍 기법에 대한 요구가 증가.
Data Parallelism과 Task Parallelism으로 나누워지는데,
Data Parallelism는 대량의 데이터를 처리함에 있어 각 CPU에게 일을 주고 동시에 병렬로 처리
-> 일반적으로 쓰레드 당 처리 내용은 동일
Task Parallelism는 큰 Task를 분할하여 각 쓰레드들이 나눠서 다른 작업 Task들을 실행

예제 소스 1 - Data Parallelism

다중 CPU에서 다중 쓰레드가 병렬로 데이터를 분할하여 처리하는 기능 제공

// 1. 순차적 실행
 // 동일쓰레드가 0~999 출력
 //
 for (int i = 0; i < 1000; i++)
 {
     Console.WriteLine("{0}: {1}",
         Thread.CurrentThread.ManagedThreadId, i);
 }
 Console.Read();

 // 2. 병렬 처리
 // 다중쓰레드가 병렬로 출력
 //
 Parallel.For(0, 1000, (i) => {
     Console.WriteLine("{0}: {1}",
         Thread.CurrentThread.ManagedThreadId, i);
 });

예제 소스 2 - 순차처리 vs Parallel 병렬처리

대량의 데이터를 여러 쓰레드가 나눠서 처리하는 병렬 처리는 많은 경우에는 순차적으로 처리하는 것보다 빠를 가능성이 큼.

const int MAX = 10000000;
const int SHIFT = 3;

static void SequentialEncryt()
{            
    // 테스트 데이타 셋업
    // 1000 만개의 스트링
    string text = "I am a boy. My name is Tom.";
    List<string> textList = new List<string>(MAX);
    for (int i = 0; i < MAX; i++)
    {
        textList.Add(text);
    }

    // 순차 처리 (Test run: 8.7 초)
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    watch.Start();
    for (int i = 0; i < MAX; i++)
    {
        char[] chArr = textList[i].ToCharArray();

        // 모든 문자를 시저 암호화
        for (int x = 0; x < chArr.Length; x++)
        {
            // 시저 암호
            if (chArr[x] >= 'a' && chArr[x] <= 'z')
            {
                chArr[x] = (char)('a' + ((chArr[x] - 'a' + SHIFT) % 26));
            }
            else if (chArr[x] >= 'A' && chArr[x] <= 'Z')
            {
                chArr[x] = (char)('A' + ((chArr[x] - 'A' + SHIFT) % 26));
            }
        }

        // 변경된 암호로 치환
        textList[i] = new String(chArr);
    };
    watch.Stop();
    Console.WriteLine(watch.Elapsed.ToString());
}

static void ParallelEncryt()
{
    // 테스트 데이타 셋업
    // 1000 만개의 스트링
    string text = "I am a boy. My name is Tom.";
    List<string> textList = new List<string>(MAX);
    for (int i = 0; i < MAX; i++)
    {
        textList.Add(text);
    }

    // 병렬 처리 (Test run: 6.1 초)
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    watch.Start();
    Parallel.For(0, MAX, i =>
    {
        char[] chArr = textList[i].ToCharArray();

        // 모든 문자를 시저 암호화
        for (int x = 0; x < chArr.Length; x++)
        {
            // 시저 암호
            if (chArr[x] >= 'a' && chArr[x] <= 'z')
            {
                chArr[x] = (char)('a' + ((chArr[x] - 'a' + SHIFT) % 26));
            }
            else if (chArr[x] >= 'A' && chArr[x] <= 'Z')
            {
                chArr[x] = (char)('A' + ((chArr[x] - 'A' + SHIFT) % 26));
            }
        }

        // 변경된 암호로 치환
        textList[i] = new String(chArr);
    });
    watch.Stop();
    Console.WriteLine(watch.Elapsed.ToString());
}

예제 소스 3 - Parallel.Invoke

여러 작업들을 병렬로 처리하는 기능을 제공

static void RunTasks()
{
    // 5개의 다른 Task들을 병렬로 실행
    Parallel.Invoke(
        () => { method1(); },
        () => { method2(); },
        () => { method3(); },
        () => { method4(); },
        () => { method5(); }
    );

    //...
}

예제 소스 4 - nonGenericCollection

제네릭이 아닌 컬렉션에 사용법

Parallel.ForEach(nonGenericCollection.Cast<object>(),
    currentElement =>
    {
    });
출처 및 참조 : http://www.csharpstudy.com/
profile
안녕하세요. 데이터와 동고동락 중인 개발자 입니다.

0개의 댓글