프로그래밍/Parallel Programming

병렬 프로그래밍 Parallel Programming - parallel_invoke

nanze 2021. 12. 26. 22:11
반응형

이전 정리글은

2021.12.22 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - parallel_for

 

메리 크리스마스. ~! 예전에는 크리스마스 때 설렘이 있었는데 나이를 먹었나보다. ㅜㅜ

자 오늘은 parallel_invoke 에 대해서 정리해보자구~

parallel_invoke

이 함수는 여러개의 작업을 동시에 실행하고자 다룰 때 유용하다. 언제나 그랬듯이 코드를 보자 ㅎ,.ㅎ

#include <ppl.h>
#include <string>
#include <iostream>

using namespace std;

template <typename T>
T addself(const T& p)
{
    return p + p;
}

int _tmain()
{
    int i = 12;
    short j = 15;
    double k = 0.4;
    wstring ws = L"Add self ";
    
    concurrency::parallel_invoke(
        [&]{ i = addself(i); },
        [&]{ j = addself(j); },
        [&]{ k = addself(k); },
        [&]{ ws = addself(ws); }
    );
    
    wcout << i << endl;
    wcout << j << endl;
    wcout << k << endl;
    wcout << ws << endl;
 
    return 0;
}

위 코드를 보면 parallel_invoke 함수는 여러 함수를 동시에 실행시킬 수 있다. parallel_invoke 함수는 내부적으로 structed_task_group을 이용하는 것으로 알고있다. 최소 2개의 작업에서부터 최대 10까지 작업을 지원하며 모든 작업이 끝날 때까지 대기한다. 당연히 작업간의 실행 순서는 보장받지 못한다. 단순한 작업을 여러개 동시에 실행시킨다면 써먹기 좋은 것이라 생각되는 함수이다. 

 이번에는 parallel_transform 함수를 알아보자. 

parallel_transform

코드부터 보도록 하자.

#include <ppl.h>
#include <array>
#include <numeric>
#include <iostream>
#include <windows.h>

using namespace std;

bool is_odd(int n)
{
    return ( n % 2 == 0) ? false : true;
}

int _tmain()
{
	array<int, 99999> ar;
	int i = 1;
	for(int& num : ar)
	{
		num = i;
		i++;
	}
	
	concurrency::parallel_transform(begin(ar), end(ar), begin(ar), [](int i) {
		return is_odd(i);
	}
	);

	i = 0;
	for (int num : ar)
	{
		wcout << num << endl;
		i++;
		if (i == 10)
			break;
	}

    return 0;
}

 처음 배열에 각 인덱스 값으로 1부터 채워놓고 있다. 그다음 parallel_transform 함수에서 각 인덱스의 값이 홀수인지를 검사하여 해당 값을 홀수이면 1 짝수이면 0으로 변경하고 있다. 이처럼 해당 컨테이너에 인덱스 별로 값을 변형시키고자 할 때 사용한다. 

 

다음은 대상 컨테이너의 값을 합치는 병렬 함수에 대해 알아보자

바로 그것은 parallel_reduce 함수이다. 

위 코드에서부터 살짝 변형시키보자.

#include <ppl.h>
#include <array>
#include <numeric>
#include <iostream>
#include <windows.h>

using namespace std;

bool is_odd(int n)
{
    return ( n % 2 == 0) ? false : true;
}

int _tmain()
{
    int value = 0;
	array<int, 99999> ar;
	int i = 1;
	for(int& num : ar)
	{
		num = i;
		i++;
	}
	
	concurrency::parallel_transform(begin(ar), end(ar), begin(ar), [](int i) {
		return is_odd(i);
	}
	);

    value = concurrency::parallel_reduce(begin(ar), end(ar), 0);
    
    wcout << L"total : " << value << endl;

    return 0;
}

배열의 각 원소 값이 홀수인지 판단하여 0 또는 1로 변경하였고 parallel_reduce 함수를 통하여 해당 값을 모두 더하였다. 결과는 50000이 나온다. STL 에는 parallel_transform 과 parallel_reduce 에 대응하는 함수 transform 과 accumulate 함수가 있다. 하지만 병렬 수행을 하지 않으니 대상 컨테이너가 많은 원소를 포함할 경우 그 수행 시간 차이는 커질 수 밖에 없다.

 크리스마스도 정말 훅 가는구나 ㅜㅜ 날씨 오질게 춥고. 다들 감기 조심하시고 특히 마스크 잘쓰시고 다니시기를. 코로나가 빨리 없어지길 기도하며 :)

 

다음 정리글은

2021.12.28 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - parallel_sort

반응형