프로그래밍/Parallel Programming

병렬 프로그래밍 Parallel Programming - concurrent_unordered_map

nanze 2022. 1. 3. 11:50
반응형

이전 정리글은

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

 

자 오늘은 일곱번째 정리시간이다. 호랑이해 들어 첫 포스팅이다. 이번 해에는 호랑이 기운 받아 모든 일이 힘차게 잘 나아가서 순조롭게 풀렸으면 한다. 방문하신 모든 분들도.~! 

첫번째로 알아볼 것은 이전시간에 다른 자료구조이다. 병렬 멀티셋을 알아보자.

concurrency::concurrent_unordered_multiset

해당 자료구조는 중복 값을 가질 수 있는 set 이라고 생각하면 된다.

코드를 보자.

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

using namespace std;

int main()
{
    concurrency::concurrent_unordered_multiset<char> mset;
    
    concurrency::parallel_for(0, 100, [&](int i)
        {
            mset.insert('a' + (i % 4 ));
        }
    );
    
    for_each(begin(mset), end(mset), [](char t)
        {
            wcout << L"character : "<< t << endl;
        }
    );
    
    return 0;
}

마지막에 set 안의 원소 값을 출력해보면 값이 순차적으로 들어가지 않고 잘 채워진 것을 확인할 수 있다.

다음은 중복 값을 허락되지 않는 일반적인 set 이다.

concurrency::concurrent_unordered_set

코드는 위와 동일하다.

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

using namespace std;

int main()
{
    concurrency::concurrent_unordered_set<char> mset;
    
    concurrency::parallel_for(0, 100, [&](int i)
        {
            mset.insert('a' + (i % 4 ));
        }
    );
    
    for_each(begin(mset), end(mset), [](char t)
        {
            wcout << L"character : "<< t << endl;
        }
    );
    
    return 0;
}

하지만 위의 코드는 중복을 허락하지 않는 set 이므로 결과가 다르다는 것을 알 수 있다. 

다음은 우리가 매우 자주쓰는  map의 병렬 버전이다. 

concurrency::unordered_map

STL 의 일반적인 unordered_map 과 차이점은 thread-safe 한 함수를 부분 제공한다는 것이다. 제공하는 함수들 중 unsafe 로 시작하는 함수들은 당연히 thread-safe 하지 않으며 thread-safe 한 함수들에 대해서 나열해보자. 

size equal_range insert operator[] cend end cbegin
hash_function max_size empty find begin at insert

코드를 보자.

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

using namespace std;

int main()
{
    concurrency::concurrent_unordered_map<char, int> cmap;
    concurrency::parallel_for(0, 100, [&](int i)
        {
            char c = 'a' + (i%3);
            cmap.insert(make_pair(c, i));
        }
    );
    
    for_each(begin(cmap), end(cmap), [](const pair<char, int>& in)
        {
            wcout << L"key : "<< in.first << " value : " << in.second << endl;
        }
    );
    
    return 0;
}

모두 알겠지만 map 은 중복 값을 허락하지 않기에 출력은 'a', 'b', 'c' 키 값만 존재한다.

다음은 map 이지만 키 값에 여러개의 값을 가질 수 있는 multimap 이다. 

concurrency::concurrent_unordered_multimap

멀티맵은 중복 값을 허용하기에 insert 함수가 pair<iterator, bool> 을 반환한다. 

코드는 위의 동일 코드를 사용해보도록 하자.

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

using namespace std;

int main()
{
    concurrency::concurrent_unordered_multimap<char, int> cmap;
    concurrency::parallel_for(0, 100, [&](int i)
        {
            char c = 'a' + (i%3);
            cmap.insert(make_pair(c, i));
        }
    );
    
    for_each(begin(cmap), end(cmap), [](const pair<char, int>& in)
        {
            wcout << L"key : "<< in.first << " value : " << in.second << endl;
        }
    );
    
    return 0;
}

이전 코드 결과와는 다르게 같은 키 값에 여러개의 값을 가지는 것을 알 수 있다.

자 새해 첫날 포스팅으로 ppl 에서 제공되는 병렬 자료구조 set, multiset, map, multimap 에 대해서 알아보았다. 

다음은 병렬 작업의 제어를 위해 필수(?)적인 취소 메카니즘에 대해서 알아보도록 하자. 

다음 정리 시간에.

 

다음 정리글은

2022.01.03 - [프로그래밍/Parallel Programming] - 병렬 프로그래밍 Parallel Programming - cancellation_token

반응형