프로그래밍/Parallel Programming

병렬 프로그래밍 Parallel Programming - parallel_sort

nanze 2021. 12. 28. 12:07
반응형

이전 정리글은

2021.12.26 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - parallel_invoke

 

자. 오늘은 병렬 방식을 이용한 정렬 함수에 대해 알아보자. 

첫번째로 알아볼 함수는 parallel_sort 함수이다. 해당 함수는 std::sort 함수의 다중 프로세스 버전이라고 생각하면 될 것 같다.

자 코드를 보자구~!!

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

using namespace std;

int _tmain()
{
	vector<int> vecIntegers(100000);
	generate(begin(vecIntegers), end(vecIntegers), mt19937(79));
	concurrency::parallel_sort(begin(vecIntegers), end(vecIntegers));

	wcout << "index [0] : " << vecIntegers[0] << endl;
	wcout << "index [50000] : " << vecIntegers[50000] << endl;
	wcout << "index [99999] : " << vecIntegers[99999] << endl;

	return 0;
}

위 코드를 보면 generate 함수를 통하여 벡터 내 난수를 생성하고 parallel_sort 를 통하여 정렬을 한 것이다. 실제로 실행보면 세 군데 출력한 부분에서 정상적으로 정렬된 것을 알 수 있다. 

다음은 동일한 정렬 함수이지만 추가적인 메모리를 사용하여 조금 더 성능을 개선시킨 버전 parallel_buffered_sort 이다. 위와 동일한 코드이지만 실행 속도 상에서 차이가 날 것이다. 적은 개수가 아닌 많은 개수를 포함한 컨테이너를 대상으로 할 경우 그 차이가 더 느껴진다. 

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

using namespace std;

int _tmain()
{
	vector<int> vecIntegers(100000);
	generate(begin(vecIntegers), end(vecIntegers), mt19937(79));
	concurrency::parallel_buffered_sort(begin(vecIntegers), end(vecIntegers));

	wcout << "index [0] : " << vecIntegers[0] << endl;
	wcout << "index [50000] : " << vecIntegers[50000] << endl;
	wcout << "index [99999] : " << vecIntegers[99999] << endl;

	return 0;
}

마지막으로 parallel_radixsort에 대해서 알아보자. 해당 함수는 이전 두 함수에 비해 더 성능이 좋으며 내부적으로 해시를 사용한다. 인자의 마지막 값으로 해시 함수를 입력받으며 생략되었을 경우 기본적으로 std::hash 함수를 이용한다. 코드를 보자.~!

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

using namespace std;

typedef struct _Vector
{
    int x;
    int y;
    int z;
}vec3;

int addedLength(const vec3& v1, const vec3& v2)
{
    int tx = v1.x + v2.x;
    int ty = v1.y + v2.y;
    int tz = v1.z + v2.z;
    return static_cast<int>(sqrt((tx*tx) + (ty*ty) + (tz*tz)));
}

int _tmain()
{
    vec3 basicVector = {2, 7, 8};
    
    vector<vec3> vecVectors3(5);
    mt19937 random(79);
    
    generate(begin(vecVectors3), end(vecVectors3), [&random]{
    		vec3 vec = { random()% 100, random()% 100, random()% 100 };
    		return vec;
        }
    );
    
    concurrency::parallel_radixsort(begin(vecVectors3), end(vecVectors3), 
        [basicVector](const vec3& target)-> int{
            return addedLength(basicVector, target);
        }
    );
    
    for_each(begin(vecVectors3), end(vecVectors3), [basicVector](const vec3 vec)
        {
            wcout << L"x : " << vec.x << L" y: " << vec.y << L" z: " << vec.z << endl;
        }
    );
    
    return 0;
}

위 코드는 두 개의 벡터를 더한 후 그 크기를 정렬 요소로 사용하는 것이다. 결과를 수행하면 기준 벡터로부터 합의 벡터 크기가 작은 순서대로 정렬된 것을 알 수 있다.

세 함수 중 가장 성능이 좋은  것은 parallel_radixsort 이나 조건이나 상황에 따라 잘 선택해서 사용해야 할 듯 하다. 

세상엔 너무 많은 지식들이 있는 것 같다.  나의 뇌여 받아들여라 ㅋ,.ㅋ

 

다음 정리글은

2021.12.30 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - concurrent_vector

 

반응형