Visual C++10을 활용한 병렬 프로그래밍

74
마마마마 마마마마마마 Server Programmer 마마마 Microsoft Visual C++ MVP Twitter : @jacking75 Visual Studio 2010 을 을을을 C++ 을을 을을을을을

Transcript of Visual C++10을 활용한 병렬 프로그래밍

Page 1: Visual C++10을 활용한 병렬 프로그래밍

마이에트 엔터테인먼트 Server Programmer

최흥배

Microsoft Visual C++ MVP

Twitter : @jacking75

Visual Studio 2010 을 활용한 C++ 병렬 프로그래밍

Page 2: Visual C++10을 활용한 병렬 프로그래밍

1. Multi-Core 시대2. 어려운 병렬 프로그래밍3. 진화4. Concurrency Runtime5. 병렬 패턴 라이브러리 ( PPL )

목차

Page 3: Visual C++10을 활용한 병렬 프로그래밍

Multi-Core 시대

Page 4: Visual C++10을 활용한 병렬 프로그래밍

Multi-Core 컴퓨터는 이미 일반화

Page 5: Visual C++10을 활용한 병렬 프로그래밍

throughput 컴퓨팅 시대

• 싱글 CPU 의 스피드 향상의 한계에 도달 .

• 멀티 코어 CPU 로 방향을 바꿈 .

• throughput 가 최대 중요 요소가 됨 .

• Intel, AMD 의 CPU 아키텍처는 Multi-Core 를 넘어서 heterogeneous( 헤테로지니아스 ) 로 가고 있음 .

Page 6: Visual C++10을 활용한 병렬 프로그래밍
Page 7: Visual C++10을 활용한 병렬 프로그래밍

• 2 코어를 융합한 클러스터 .

• 「 Bulldozer Module 」이라고 부른다 .

• 2 개의 스레드를 병렬로 실행할 수 있는 모듈이 Bulldozer의 기본 단위 . 기본은 하나가 아니고 두 개다 !!!

• 4 코어의 Bulldozer CPU 라면 두 개의 Bulldozer Mod-ule 을 탑재 .

• Hyper-Threading 이 아니다 !!!

AMD - Bulldozer 아키텍처

Page 8: Visual C++10을 활용한 병렬 프로그래밍

• Intel 의 Hyper-Threading 에서는 CPU 전체의 자원을 명령 단위로 2 개의 스레드에서 공유한다 .

• Bulldozer 에서는 CPU 의 자원 중 정수 연산 파이프는 2 개의 스레드가 각각 전용 파이프를 가진다 .

• 그러나 명령 디코더나 부동 소수점 연산 유닛 등은 2개의 스레드에서 공유한다 .

• 정수 연산에서는 스레드간의 경합이 없기 때문에 throughput 가 높다 ,

Hyper-Threading 과의 차이

Page 9: Visual C++10을 활용한 병렬 프로그래밍
Page 10: Visual C++10을 활용한 병렬 프로그래밍
Page 11: Visual C++10을 활용한 병렬 프로그래밍

Intel - Larrabee 아키텍처

• 현재 Intel 은 「 Larrabee( 라라비 ) 」를 그래픽스 제품으로서 투입하는 것을 단념 .

• 그러나 Intel 이 CPU 에 통합하기 위한 데이터 병렬 중시형 프로세서 코어의 아키텍처를 긴급하게 필요로 하고 있는 점은 변화지 않음 .

• Larrabee 의 목적은 어떻게 하면 유연하고 고효율이면서 프로그램 하기 쉬운 아키텍처로 할 수 있을지를 추구하는 것 .

• Intel 의 간부들은 Larrabee 와 같은 범용 데이터 병렬 코어를 CPU 로 통합하는 것을 전망 .

Page 12: Visual C++10을 활용한 병렬 프로그래밍

• 효율성으로 말하면 대형 슈퍼 스칼라 코어와 소형의 데이터 병렬 특화형 코어의 편성의 헤테로지니아스 ( 이종 혼합 ) 구성이 바람직하다 .

• 왜냐하면 지금부터 퍼포먼스를 늘리고 싶은 것은 데이터 병렬로 부동 소수점 연산 중심의 작업 부담량이기 때문 .

• Amdahl 의 법칙은 여전히 살아 있기 때문에 Intel 은 대형 슈퍼 스칼라 코어를 버리고 가는 것도 할 수 없다 . 필연적으로 헤테로지니아스가 된다 .

Page 13: Visual C++10을 활용한 병렬 프로그래밍
Page 14: Visual C++10을 활용한 병렬 프로그래밍

어려운 병렬 프로그래밍

Page 15: Visual C++10을 활용한 병렬 프로그래밍

병렬 프로그래밍 ? Multi-Core? 그거 먹는 건가요 ? 우걱우걱

Page 16: Visual C++10을 활용한 병렬 프로그래밍

race condition, dead lock

Page 17: Visual C++10을 활용한 병렬 프로그래밍

void SetReUseSocket(){ ……… if( flase == m_bUsed ) { LOG(“SetReUseSocket() | Failed”); return; }

LOG(“SetReUseSocket()”);

m_bUsed = true; ………}

Page 18: Visual C++10을 활용한 병렬 프로그래밍
Page 19: Visual C++10을 활용한 병렬 프로그래밍

진화

Page 20: Visual C++10을 활용한 병렬 프로그래밍

2002 년 2010 년

Page 21: Visual C++10을 활용한 병렬 프로그래밍

OS – 2001 년과 2009 년

Windows XP Windows 7

Page 22: Visual C++10을 활용한 병렬 프로그래밍

Visual Studio – 2002 년과 2010 년

Visual Studio.NET( 2002)

Visual Studio 2010

Page 23: Visual C++10을 활용한 병렬 프로그래밍

2008 년 10 월 Microsoft 의 최고 연구 전략 책임자를 맡은 Craig Mundie 씨

- Win32 는 비동기 병렬 컴퓨팅에는 적합하지 않는 것을 인정 .

- Windows 7 및 Windows Server 2008 R2 에서 문제 해결을 위해 첫발을 내딪음 .

- Windows 는 지금이라도 2,3 의 코어 머신을 처리할 수 있지만 8, 16 또는 32 이상의 코어 머신을 사용하도록 설계되어 있지 않다 .

- Windows 를 보다 뛰어난 병렬 / 비동기 프로세싱 플랫폼화 하기 위한 최초의 씨앗은 2009 년부터 뿌려지기 시작 .

Page 24: Visual C++10을 활용한 병렬 프로그래밍

Core 2

Thread3

Non-running threads

Core 1

Thread4

Thread5

Thread1

Thread2

Thread6

Core 2Core 1

UserThrea

d2

KernelThrea

d2

UserThrea

d1

KernelThrea

d1

UserThrea

d3

KernelThrea

d3

UserThrea

d4

KernelThrea

d4

UserThrea

d5

KernelThrea

d5

UserThrea

d6

KernelThrea

d6

Thread Scheduling

UMS - Cooperative Schedul-ing

그림 출처 : PDC 09

Page 25: Visual C++10을 활용한 병렬 프로그래밍

• 대기 중인 스레드의 커널 모드에서의 Block 이 풀리면

• 대응하는 유저 모드 스레드는 Completion List 에 등록되어

• 코어에서 실행 중인 스레드가 종료하는 것을 기다린 후 다시 실행한다 .

UMS - Completion List

Page 26: Visual C++10을 활용한 병렬 프로그래밍

Group

NUMA NodeSocket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

Socket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

NUMA NodeSocket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

Socket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

Group

NUMA NodeSocket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

Socket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

NUMA NodeSocket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

Socket

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

CoreLP

LP

LP

LP

NUMA

그림 출처 : PDC 09

Page 27: Visual C++10을 활용한 병렬 프로그래밍

Parallel Pattern Library

Resource Manager

Task Scheduler

ThreadsOperat-ing Sys-tem

Native Concurrency Runtime

Data

Str

uctu

res

AsynchronousAgentsLibrary

UMS Threads

Native LibrariesIn

tel

® Open

MP

Inte

l ® T

BB

ToolsVisual Stu-dio 2010

ParallelDebug-

gerProfiler Concur-rency

Analysis

Intel Paral-lel Studio

Parallel Com-poserParallel

Inspec-tor

Parallel Amplifier

Concurrency Runtime

그림 출처 : PDC 09

Page 28: Visual C++10을 활용한 병렬 프로그래밍

Concurrency Runtime(ConcRT)

Page 29: Visual C++10을 활용한 병렬 프로그래밍

Resource Manager

Task Scheduler

OS

Parallel Patterns Library

Asynchronus Agents Library

Synchronization Data Struc-tures

Page 30: Visual C++10을 활용한 병렬 프로그래밍

• 작업을 작고 세밀하게 처리할 수 있도록 범용적인 컨테이너와 알고리즘 제공

• Imperative parallelism – parallel_for, parallel_for_each 등

• Task parallelisn – task_group, structured_task_group

Parallel Patterns Library(PPL)

Page 31: Visual C++10을 활용한 병렬 프로그래밍

• Actor 베이스 모델 및 메시지 전달을 통해서 작고 세밀한 data flow 와 task pipeniling 을 제공

• AAL 은 다른 컴포넌트의 데이터를 기다리면서 작업을 처리 할 수 있다 .

• AAL 은 복수의 엔티티가 서로간에 비동기로 통신을 할 때 사용한다 .

Asynchronous Agents Library(AAL)

Page 32: Visual C++10을 활용한 병렬 프로그래밍
Page 33: Visual C++10을 활용한 병렬 프로그래밍

class GameAI : public agent {..... void run() { // Send the request. ...... send(_target, wstring(L"request"));

// Read the response. int response = receive(_source); }

private: ISource<int>& _source; ITarget<wstring>& _target;};

class GameLogic : public agent {..... void run() { // Send the request. ...... send(_target, wstring(L"request"));

// Read the response. int response = receive(_source); }

private: ISource<int>& _source; ITarget<wstring>& _tar-get;};

Page 34: Visual C++10을 활용한 병렬 프로그래밍

• 여러 스레드로부터 공유 데이터 접근을 동기화 할 수 있는 몇 개의 데이터 구조를 제공 .

• 동기 오브젝트는 크리티컬 섹션과 같이 다른 스레드로부터 공유 데이터를 사용할 수 있을 때까지 기다린다 .

• critical_section, reader_writer_lock, event

Synchronization Data Structures

Page 35: Visual C++10을 활용한 병렬 프로그래밍

• 실행 시에 task 의 스케쥴링 및 조정을 한다 .

• cooperative 스케쥴링과 work-stealing 알고리즘을 사용하여 최대한 효율이 좋게 리소스를 처리하도록 한다 .

• Concurrency Runtime 은 기본적인 스케쥴러를 제공하므로 직접 관리할 필요는 없다 .• 다만 우리가 만든 애플리케이션에 최적화 시켜 더 높은 성능을 얻고 싶을 때는 스케줄러의 정책을 변경하거나 특별한 task, 특별한 스케줄러와 제휴할 수 있다 .

Task Scheduler

Page 36: Visual C++10을 활용한 병렬 프로그래밍

• Processors 나 메모리 등의 컴퓨팅 리소스를 관리하는 것이 목적 .

• 실행 시에 작업 부하에 변경이 일어나면 가장 효율이 좋게 처리할 수 있도록 리소스를 할당 .

• 컴퓨팅 리소스를 추상화하여 Task Scheduler 와 주로 대화 .

• 더 높은 성능을 얻기 위해서 Resource Manager 를 세밀하게 조정할 수 있다 .• 다른 병렬 라이브러리의 병행 런타임과 컴퓨팅 리소스 관리를 통합 할 수 있다 .

Resource Manager

Page 37: Visual C++10을 활용한 병렬 프로그래밍

CPU0 CPU1 … CPUN

BigBig

Big

Big

SmallSmallSmall Small

Dynamic Scheduling

CPU0 CPU1 … CPUN

Big

Big

Big

SmallSmall Small

Small

Big

Static Scheduling

Page 38: Visual C++10을 활용한 병렬 프로그래밍

ConcRT 의 Cooperative

Demo

Page 39: Visual C++10을 활용한 병렬 프로그래밍

코어 증가와 Resource Management

• 4 개의 Core 를 가진 ConcRT 를 사용한 프로세스가 두개 실행 중이라면 , 하나의 ConcRT 는 Core 0, Core 1 에서 , 두 번째 ConcRT 는 Core 2, Core 3 에서 실행

Page 40: Visual C++10을 활용한 병렬 프로그래밍

#include "stdafx.h"#include <ppl.h>using namespace Concurrency;

int main(){ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

parallel_invoke( [] { }, [] { } ); return 0;}

ConRT Memory leak?

• 위 코드는 디버그 모드에서 메모리 릭을 경고 .

• 이유는 Task Scheduler 와 Resource Manage 가 파괴되기 전에 프로그램이 종료 되기 때문 .

Page 41: Visual C++10을 활용한 병렬 프로그래밍

int main(){ HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); CurrentScheduler::Create( SchedulerPolicy() ); CurrentScheduler::RegisterShutdownEvent( hEvent );

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

parallel_invoke( [] {}, [] {} );

CurrentScheduler::Detach(); WaitForSingleObject( hEvent, INFINITE ); CloseHandle( hEvent ); Sleep(500);

return 0;}

Page 42: Visual C++10을 활용한 병렬 프로그래밍

병렬 패턴 라이브러리 ( PPL )

Page 43: Visual C++10을 활용한 병렬 프로그래밍

PPL 의 세 가지 features

• Task Parallelism

• Parallel algorithms

• Parallel containers and objects

Page 44: Visual C++10을 활용한 병렬 프로그래밍

3D 게임을 실행하면…Font 리소스 로딩Texture 리소스 로딩3D 모델링 리소스 로딩 등등…

Page 45: Visual C++10을 활용한 병렬 프로그래밍

Task Parallelism

− 실제적인 task 의 실행은 task_group 에서 한다 .

− unstructured_task_group(task_group) 와 structured_task_group 로 나누어진다 .

− task_group : 스레드 세이프 structured_task_group : 스레드 세이프 하지 않음 .

Page 46: Visual C++10을 활용한 병렬 프로그래밍

Thread Atask_group1.run( task2)

Thread Btask_group1.run( task3)

task_group1.run( task1)

Thread Astructured_task_group1.run( task2)

structured_task_group1.run( task1)

Main Thread

Main Thread

Page 47: Visual C++10을 활용한 병렬 프로그래밍

초 간단 !!! task 사용 방법1. ppl.h 파일을 포함합니다 .

#include <ppl.h>

2. Concurrency Runtime 의 네임 스페이를 선언합니다 . using namespace Concurrency;

3. 태스크 그룹을 정의합니다 .structured_task_group structured_tasks;

4. 태스크를 정의합니다 . auto structured_task1 = make_task([&] { Plus(arraynum1, true); } );

5. 태스크를 태스크 그룹에 추가한 후 실행합니다 .  structured_tasks.run( structured_task1 );

6. 태스크 그룹에 있는 태스크가 완료될 때까지 기다립니다 . structured_tasks.wait();

Page 48: Visual C++10을 활용한 병렬 프로그래밍

ConcRT 의 Task

Demo

Page 49: Visual C++10을 활용한 병렬 프로그래밍
Page 50: Visual C++10을 활용한 병렬 프로그래밍

for( i = 0; i < 1000000; ++i ){ ………… …………}

Page 51: Visual C++10을 활용한 병렬 프로그래밍

Parallel Algorithms

− 데이터 컬렉션을 대상으로 쉽게 병렬 작업을 할 수 있게 해주는 알고리즘들 .

− STL 에서 제공하는 알고리즘과 비슷한 모양과 사용법 .

− paeallel_for, parallel_for_each, parallel_invoke 가 구현되어 있음 .

parallel_accumulate, parallel_partial_sum 는 다음 버전 ?

Page 52: Visual C++10을 활용한 병렬 프로그래밍

parallel_for− for 문을 병렬화 .

− for 문과 사용 방법이 흡사하여 쉽게 변환 .

− step 값을 지정하는 버전과 지정하지 않는 버전 두 개가 있음 (지정하지 않으면 1).

− index 조사는 ‘<‘만 지원 .

Page 53: Visual C++10을 활용한 병렬 프로그래밍

초 간단 !!! parallel_for 사용 법1. ppl.h 파일을 포함합니다 .

#include <ppl.h>

2. Concurrency Runtime 의 네임 스페이를 선언합니다 . using namespace Concurrency;

3. parallel_for 에서 호출할 함수 정의

4. parallel_for 에서 사용할 data set 정의 .

5. parallel_for 사용 .

Page 54: Visual C++10을 활용한 병렬 프로그래밍

parallel_for_each

− STL 의 for_each 알고리즘을 병렬화 .

− for_each 와 사용 방법이 같음 .

Page 55: Visual C++10을 활용한 병렬 프로그래밍

초 간단 !!! parallel_for_each 사용 법1. ppl.h 파일을 포함합니다 .

#include <ppl.h>

2. Concurrency Runtime 의 네임 스페이를 선언합니다 . using namespace Concurrency;

3. parallel_for_each 에서 호출할 함수 정의

4. parallel_for_each 에서 사용할 data set 정의 .

5. parallel_for_each 사용 .

Page 57: Visual C++10을 활용한 병렬 프로그래밍
Page 58: Visual C++10을 활용한 병렬 프로그래밍

parallel_invoke

− 병렬로 일련의 태스크 실행 .

− 동시 실행할 복수의 독립된 태스크를 실행할 때 좋음 .

− task_group 과 비슷하나 사용방법은 더 쉬움그러나 최대 10 개의 태스크만 병렬 작업이 가능하다 .

Page 59: Visual C++10을 활용한 병렬 프로그래밍

초 간단 !!! parallel_invoke 사용 법1. ppl.h 파일을 포함합니다 .

#include <ppl.h>

2. Concurrency Runtime 의 네임 스페이를 선언합니다 . using namespace Concurrency;

3. 태스크 정의

4. parallel_invoke 사용 .

Page 61: Visual C++10을 활용한 병렬 프로그래밍

parallel objects - combinable

− 스레드 세이프한 오브젝트 .

− 계산 실행 후 최종 결과에 그 계산 결과를 통합하는 재 사용 가능한 로컬 스트리지 제공 .

− 복수의 스레드 또는 태스크 간에 공유 리소스가 있는 경우 편리 .

− lock-free thread-local sub-computations during parallel al-gorithms

− combinable 클래스에 사용할 데이터는 기본 생성자와 복사 생성자를 가지고 있어야 한다 .

− Win32 API 의 thread local storage 와 비슷 .

− combine, combinable_each 제공

Page 62: Visual C++10을 활용한 병렬 프로그래밍
Page 63: Visual C++10을 활용한 병렬 프로그래밍
Page 64: Visual C++10을 활용한 병렬 프로그래밍

concurrent containers

− 병렬 환경에서 스레드 세이프하게 데이터를 저장 .

− concurrent_queue, concurrent_vector,.

− concurrent_hash_map 은 다음 버전 ?

Page 65: Visual C++10을 활용한 병렬 프로그래밍

concurrent_vector• 병렬 프로그래밍에 접합한 STL vector 타입의 컨테이너 .

• 전체적인 인터페이스는 vector 와 비슷하나 제한이 있슴 .

• 기존 요소의 값을 변경할 때는 스레드 세이프하지 않음 . 기존 요소의 값을 변경할 때는 동기화 객체를 사용하여 lock 을 걸어야 합니다 .

• concurrent_vector 사용 방법- concurrent_vector 를 사용하기 위해서 먼저 헤더 파일을 포함해야 합니다 .- concurrent_vector 의 헤더 파일은 “ concurrent_vector.h” 입니다 .- STL 의 vector 사용 방법과 거의 같음 .

Page 66: Visual C++10을 활용한 병렬 프로그래밍

기능 vctor Concurrent_vector

추가 스레드에 안전하지 않음 스레드에 안전

요소에 접근 스레드에 안전하지 않음 스레드에 안전

반복자 접근 및 순회 스레드에 안전하지 않음 스레드에 안전push_back 가능 가능insert 가능 불가능clear 모두 삭제 모두 삭제erase 가능 불가능pop_back 가능 불가능

배열식 접근 예 . &v[0]+2

가능 불가능

grow_by, grow_to_at_least (vector의 resize 와 비슷 ) 는 스레드에 안전하지 않음

추가 또는 resize 때 기존 인덱스나 반복자의 위치가 바뀌지 않음

bool 형은 정의 되지 않았음

Page 67: Visual C++10을 활용한 병렬 프로그래밍

concurrent_deque• 병렬 프로그래밍에 접합한 STL deque 타입의 컨테이너 .

• enqueue 와 dequeue 조작이 스레드 세이프 하다 .

• 반복자를 지원하지만 스레드 세이프 하지 않다 .

• front 와 pop 함수를 지원하지 않음 . 대신에 try_pop 함수를 대신해서 사용 .

• back 함수를 지원하지 않는다 . 그러므로 마지막 요소를 참조하는 것은 불가능하다 .

• size 메소드 대신 unsafe_size 함수를 지원한다 . unsafe_size 는 이름 그대로 스레드 세이프 하지 않다 .

• 사용 방법 - “concurrent_queue.h” 파일을 include 한다 . - 사용 방법은 STL 의 deque 와 비슷 .

Page 68: Visual C++10을 활용한 병렬 프로그래밍

스레드 세이프한 concurrent_queue 의 함수

- concurrent_queue 에 enqueue 또는 dequeue 하는 모든 조작에 대해서는 스레드 세이프합니다 .- empty- push- get_allocator- try_pop- empty 는 스레드 세이프하지만 empty 호출 후 반환되기 전에 다른 스레드에 의해서 queue 가 작아지던가 커지는 경우 이 동작들이 끝난 후에 empty 의 결과가 반환됩니다 .

스레드 세이프 하지 않은 concurrent_queue 의 함수

- clear- unsafe_end- unsafe_begin- unsafe_size

Page 69: Visual C++10을 활용한 병렬 프로그래밍

Intel 의 TBB 를 배운 후 ConcRt 를 보면……

ConcRt 를 배운 후 TBB 를 보면……

Page 70: Visual C++10을 활용한 병렬 프로그래밍
Page 71: Visual C++10을 활용한 병렬 프로그래밍

참고

Page 72: Visual C++10을 활용한 병렬 프로그래밍

AMD 가 차기 아키텍쳐 「 Bulldozer 」와「 Bobcat 」의 개요를 공표원문 : http://pc.watch.impress.co.jp/docs/column/kaigai/20091112_328392.html번역 :http://jacking.tistory.com/487http://jacking.tistory.com/488http://jacking.tistory.com/489

2011 년에 등장하는 AMD 의 8 코어 데스크탑 CPU 「 Zambezi 」원문http://pc.watch.impress.co.jp/docs/column/kaigai/20091126_331235.html번역http://jacking.tistory.com/514http://jacking.tistory.com/515http://jacking.tistory.com/516

Core i5/i7원문http://www.atmarkit.co.jp/fwin2k/words/011corei5/corei5.html번역http://jacking.tistory.com/510http://jacking.tistory.com/511

Page 73: Visual C++10을 활용한 병렬 프로그래밍

계획이 바뀐 Larrabee 무엇이 문제였는가 ?http://jacking.tistory.com/517http://jacking.tistory.com/518

마이크로소프트 Windows 7 에서도 병렬처리 향상을 목표로 http://jacking.tistory.com/355

[PDC09] Developing Applications for Scale-Up Servers Run-ning Windows Server 2008 R2http://microsoftpdc.com/Sessions/SVR18

[PDC09] Lighting up Windows Server 2008 R2 Using the Con-cRT on UMShttp://microsoftpdc.com/Sessions/SVR10

양보할 줄 아는 Concurrency Runtime 의 eventhttp://vsts2010.tistory.com/109

Cross Process Resource Management - do we need it now?http://blogs.msdn.com/nativeconcurrency/archive/2010/04/07/cross-process-resource-management-do-we-need-it-now.aspx

Page 74: Visual C++10을 활용한 병렬 프로그래밍

Concurrency::task_group leaks memoryhttp://social.msdn.microsoft.com/Forums/en/parallelcppnative/thread/15799a79-cca0-4c51-85e3-64ea1e26981d

MSDN – Concurrency Runtimehttp://msdn.microsoft.com/en-us/library/dd504870(VS.100).aspx

VSTS 2010 스터디 블로그http://vsts2010.net

Parallel Programming in Native Codehttp://blogs.msdn.com/nativeconcurrency/default.aspx

본인 블로그http://jacking.tistory.com/