The Parallel objects of PPL(Parallel Pattern Library).
Brief introduction of Concurrency::combinable class, example,
discussion
PPL(병렬 패턴 라이브러리)의 병렬 객체
Concurrency::combinable 클래스에 대한 간단한 소개, 예제, 여담
2. 김용준
- 스레드 로컬 저장소(Thread-local storage)를 구현한 클래스
- 각 스레드별로 값을 저장하고 작업이 완료되면 모든 값을 하나로 병합하여
결과를 도출 할 수 있음
- 객체에 접근할 때 동기화 과정이 필요 없음
Concurrency::combinable class (in book)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
3. 김용준
combinable<T> 개체는 병렬 알고리즘 동안 데이터의 스레드-전용 복사본을
제공하고 잠금이 없는 스레드-로컬 하위 계산을 수행하기 위한 것입니다.
병렬 작업이 끝나면 스레드 전용 하위 계산을 최종 결과에 병합할 수 있습니
다.
이 클래스는 공유 변수 대신 사용할 수 있으며 해당 공유 변수에 대한 경합이
있는 경우 성능을 개선할 수 있습니다.
클래스 세부 내용은 MSDN을 참조합시다 ㅋㅋ
https://msdn.microsoft.com/ko-kr/library/dd492850.aspx
Concurrency::combinable class (MSDN)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
4. 김용준
The combinable<T> object is intended to provide thread-private
copies of data, to perform lock-free thread-local sub-computations
during parallel algorithms.
At the end of the parallel operation, the thread-private sub-
computations can then be merged into a final result.
This class can be used instead of a shared variable, and can
result in a performance improvement if there would otherwise be a
lot of contention on that shared variable.
Concurrency::combinable class (MSDN)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
5. 김용준
공학 분야에서 경쟁 상태(race condition)란 둘 이상의 입력 또는 조작이 동
시에 이루어지는 상태를 말한다. 이런 상태에서는 정상적인 결과가 나오지 않
게 될 위험이 있는데 이를 경쟁 위험이라고 한다.
전산학에서 경쟁 상태란 공유 자원에 대해 여러 개의 프로세스가 동시에 접근
을 시도하는 상태를 말한다. 동시에 접근할 때 자료의 일관성을 해치는 결과
가 나타날 수 있다. 이를 방지하기 위해서는 프로세스 협력 기법이 필요하다.
경쟁 상태 (wikipedia)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
6. 김용준
Race conditions arise in software when an application depends on
the sequence or timing of processes or threads for it to operate
properly. As with electronics, there are critical race conditions
that result in invalid execution and bugs as well as non-critical
race conditions that result in unanticipated behavior. Critical
race conditions often happen when the processes or threads depend
on some shared state. Operations upon shared states are critical
sections that must be mutually exclusive. Failure to obey this rule
opens up the possibility of corrupting the shared state.
Race Conditions (wikipedia)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
7. 김용준
#include <ppl.h>
#include <chrono>
#include <array>
#include <numeric>
#include <iostream>
using namespace Concurrency;
using namespace std;
// 시간 재기 위한 함수 (살짝 고침)
template <class Function>
double time_call(Function&& f)
{
auto start = chrono::system_clock::now();
f();
auto end = chrono::system_clock::now();
chrono::duration<double, milli> sec = end - start;
return sec.count();
}
bool is_prime(int n)
{
if ( n < 2 )
return false;
for (int i = 2; i < n; ++i)
{
if ( (n % i) == 0 )
return false;
}
return true;
}
Example (in book)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
int main()
{
array<int, 100000> a;
iota(begin(a), end(a), 0);
int prime_sum = 0;
double elapsed = 0;
elapsed = time_call([&] {
for_each (begin(a), end(a), [&] (int i) {
prime_sum += (is_prime(i) ? i : 0);
});
});
cout << prime_sum << endl;
cout << "serial time: " << elapsed << " ms" << endl;
iota(begin(a), end(a), 0);
elapsed = time_call([&] {
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&] (int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
});
cout << prime_sum << endl;
cout << "parallel time: " << elapsed << " ms" << endl;
}
8. 김용준
combine_each는 아래의 함수의
elapsed = time_call([&] {
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&] (int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
Combine을 combine_each로 아래의 방법으로
elapsed = time_call([&] {
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&] (int i) {
sum.local() += (is_prime(i) ? i : 0);
});
sum.combine_each([&] (int local) {
prime_sum += local;
});
사용
여담으로
prime_sum = sum.combine(plus<int>());
을 이렇게 사용해도 됨...
prime_sum = sum.combine([](const int& a, const int& b) { return a + b; });
왜 인지는 다음장에 나옴 ㅋㅋ
Example (in book)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
9. 김용준
combine (MSDN)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
template<typename _Function> _Ty combine(_Function _FnCombine) const
- Computes a final value from the set of thread-local sub-computations by calling the supplied
combine functor.
- 제공된 combine 함수를 호출하여 스레드 로컬 하위 계산 집합에서 최종 값을 계산합니다.
_Function
- The type of the function object that will be invoked to combine two thread-local sub-computations.
- 두 스레드 로컬 하위 계산을 결합하기 위해 호출할 함수 개체의 형식입니다.
_FnCombine
- The functor that is used to combine the sub-computations. Its signature is T (T, T) or T (const
T&, const T&), and it must be associative and commutative.
- 하위 계산을 결합하는 데 사용되는 함수입니다. 해당 서명은 T (T, T) 또는 T (const T&, const T&)이고 결합
성이 있고 비가환적 이어야 합니다.
10. 김용준
template<typename _Function> void combine_each(_Function _FnCombine) const
- Computes a final value from the set of thread-local sub-computations by calling the supplied
combine functor once per thread-local sub-computation. The final result is accumulated by the
function object.
- 스레드 로컬 하위 계산마다 한 번씩 제공된 combine 함수를 호출하여 스레드 로컬 하위 계산 집합에서 최종 값을
계산합니다. 최종 결과는 함수 개체에 의해 누적된 것입니다.
_Function
- The type of the function object that will be invoked to combine a single thread-local sub-
computation.
- 단일 스레드 로컬 하위 계산을 결합하기 위해 호출할 함수 개체의 형식입니다.
_FnCombine
- The functor that is used to combine one sub-computation. Its signature is void (T) or void (const
T&), and must be associative and commutative.
- 한 하위 계산을 결합하는 데 사용되는 함수입니다. 해당 서명은 void (T) 또는 void (const T&)이고 결합성이
있고 비가환적 이어야 합니다.
combine_each (MSDN)
PPL Study: Parallel Objects
PPL Study: Parallel Objects
11. 김용준
- combine이랑 combine_each의 MSDN 설명에서, Commutative를 비가환이라고 번역을
해놨는데, 비가환은 non-commutatvie 일텐데... (번역 제안하고 기다리는 중 입니다~)
- 수학에서, 집합 S 에 이항연산 * 이 정의되어 있을 때, S의 임의의 두 원소 a, b
에 대해 a * b = b * a 가 성립하면, 이 연산은 교환법칙(交換法則, commutative law)
을 만족한다고 한다. 이때 연산은 가환(可換, commutative)이라고도 한다. 교환법칙을
만족하지 않는 연산은 비가환(非可換, non-commutative)이라고 한다. (Wikipedia)
- 빼기 연산, 나누기 연산, 두 정사각 행렬 A,B에 대해 AB≠BA인 것이 대표적인 비가
환 연산
- 만약에 비가환 연산인 빼기 연산을 combine이나 combine_each의 _Function자리에
넣게 되면 그때 그때 결과가 달라지겠지요??
잡담 – Commutative / 가환
PPL Study: Parallel Objects
PPL Study: Parallel Objects
12. 김용준
정리
- 스레드에서 공유하는 변수가 경쟁상태가 될 가능성을 피하기 위해 사용
- 이 문제를 피하기 위해 스레드 로컬 저장소를 이용
- PPL에서는 Concurrency::combinable 클래스를 사용
간단하게 생각할 수 있는 실무 예시 ㅋㅋ
- 부재별 설계 항목(bending, shear 등등)을 병렬로 한방에 계산한 뒤,
ratio와 status의 계산에 사용
- 깨알같이 가볍게 병렬로 처리할 부분이 많을 것 같습니다~
- 모두 같이 토론의 장을 ㅋㅋ
Parallel Objects
PPL Study: Parallel Objects
PPL Study: Parallel Objects
13. 김용준
교재
Think About PPL을 이용한 VC++병렬 프로그래밍 (한빛미디어)
MSDN
https://MSDN.microsoft.com/en-us/library/dd504906.aspx
https://MSDN.microsoft.com/en-us/library/dd492850.aspx
Wikipedia
https://en.wikipedia.org/wiki/Race_condition
https://en.wikipedia.org/wiki/Commutative_property
참고 자료
PPL Study: Parallel Objects
PPL Study: Parallel Objects