no swim no life

TBB-02, 병렬적 사고방식 본문

work/fundamental

TBB-02, 병렬적 사고방식

달려간다 2011. 1. 7. 00:30

분해(Decomposition)
- 문제를 Task들로 분해 한다. 시작은 어디에 병렬성이 있는지 찾아보는 것이다.
   모든 것은 경우에 따라 다르다.

조정(Scaling)
- Task 관리에 대한 부담을 최소화하고, 프로세서들이 모두 가동되도록 한다.

스레드(Threads)
- 스레드와 프로세스 사이의 가장 중요한 차이점은 프로세스 안에 있는 스레드들은 그 프로세스에 대한 모든 데이터를 공유한다는 것이다.
- C++ 라이브러리에 있는 C 상속 함수 중에 asctime, ctime, gmtime, localtime, rand, strtok와 같음 함수들은 호출 사이에 내부 상태를 보유한다. 이들을 사용할 땐 스레드 안정성이 있는 버전을 확인하길 바란다. STL의 컨테이너 클래스는 일반적으로 스레드 안정성이 없다.

정확성(Correctness)
- 데드락(deadlock)은 적어도 두 개의 태스크들이 서로 기다리며, 다른 태스크가 진행될 때까지 각 태스크가 다시 시작하지 않을 경우에 발생한다. 이것은 여러개의 잠금을 얻으려고 하는 코드에서 쉽게 일어난다. 
대응)  잠금이 필요하지 않도록 암시적 동기화를 사용한다. 일반적으로 잠금의 사용을 피해야 하는데, 특히 여러 개의 잠금을 동시에 사용하는 일이 없어야 한다. 어떤 잠금을 얻은 후에 그 잠근을 사용할 수도 있는 함수나 서브루틴을 호출하면 종종 다중 잠금 문제의 원인이 되기도 한다. 이처럼 때때로 발생할 수 있는 공유된 리소스에 대한 접근 문제를 해결하기 위한 두 가지 일반적인 해결책이 있다. 즉 확실한 순서로 잠금을 얻어야 하며, 또는 잠금을 얻을 수 없어 다시 시작할 때마다 모든 잠금을 해제하는 것이다.
- 레이스 컨디션(race condition)은 여러 개의 태스크들이 적절한 동기화 없이 동일한 메모리에 읽고 쓸 때 발생한다. 때때로 race는 오류 없이 완벽하게 종료되며, 어떤 때는 비정상적으로 마친다. 레이스 컨디션은 데드락보다는 덜 비극적이지만, 더 치명적일 수도 있다.
대응) 동기화 메커니즘을 사용하고 통제된 방법으로 프로그램이 올바르게 동작하도록 관리한다. 잠금에 기반을 둔 낮은 수준의 방법론은 작업을 잘못되게 만들 수 있기 때문에 사용을 피한다. 명시적 잠금은 맨 마지막에 해야 한다. 일반적으로, 프로그래머는 가능한 알고리즘 템플릿과 태스크 스케줄러에 의해 표현되는 동기화를 사용하는 편이 더 낫다. 예를 들어, 공유 변수를 가지고 자신만의 것을 생성하는 대신에 parallel_reduce를 사용해야 한다. parallel_reduce에 있는 join 연산은 이 연산이 연결하는 하위 문제들이 완료될 때까지 parallel_reduce의 다음 과정이 실행되지 않도록 보장된다.

추상화 및 패턴(Abstraction & Patterns)
- 원초적 스레드 프로그래밍에서는 직접 스레드를 관리하는 작업이 필요한데, 이것은 시간 낭비이며 오류를 발생시킬 가능성도 높다.
- 코드는 변경이 없이 계속해서 재사용되지 않지만 패턴은 재사용된다. '병렬 프로그래밍을 위한 패턴(맷슨, Addison Wesley 출간)'

그외...

- 빈번한 동기화를 필요로 하지 않을 때, coarse-grained 병렬처리를 사용
(네명의 사람에게 편지 보내는 일을 나눈다면, 각각의 사람에게 전체 프로세스를 할당하는 형식)

'work > fundamental' 카테고리의 다른 글

-로서, -로써  (0) 2011.01.30
TBB-01, Intel Threading Building Block  (0) 2011.01.03
static inline  (0) 2011.01.03
Comments