4 15일에 하는 “C++ 개발자/게임개발자를 위한 VS2010 세미나에서 “Visual Studio 2010을 활용한 C++ 병렬 프로그래밍세션 강연을 합니다.

 

 

C++을 활용한 병렬 프로그래밍이라는 것은 VC++ 10의 새로운 기능 중 하나인 Concurrency Runtime을 활용한 병렬 프로그래밍입니다.

 

이전에 온라인 강연에서 “Concurrency Runtime”에 대해서 강연을 한 적은 있지만 이렇게 규모가 큰 곳에서 오프라인으로 하는 것은 처음입니다. “Concurrency Runtime”에 대한 공개적인 오프라인 강연은 처음이지만 이전에 온라인으로 한 적이 있고 VSTS2010 팀블로그에 제가 적은 글도 있어서 이날에는 이것만 하지 않고 병렬 프로그래밍과 관련된 다른 이야기도 합니다.

 

 

현재 만든 PT 문서의 목차는 아래와 같습니다.

 

1. Multi-Core 시대

2. 어려운 병렬 프로그래밍

3. 진화

4. Concurrency Runtime

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

 

 

페이지 수는 70페이지 정도 되지만 저는 한 페이지에 내용을 작게 넣고 그림도 꽤 있어서 실질적으로 그렇게 많은 양은 아닙니다.^^

 

목차의 내용에 대해서 간단하게 설명하자면

 

1. Multi-Core 시대

현재와 앞으로의 CPU 아키텍처에 대해서 이야기합니다. AMD Intel이 생각하는 CPU 아키텍처를 설명합니다.

 

2. 어려운 병렬 프로그래밍

병렬 프로그래밍 말은 쉽지만 실상 쉽지 않습니다. CPU 벤더들이 말하는 이상과 달리 멀티 코어를 제대로 활용하기 어려운 현실에 대한 이야기입니다.

 

3. 진화

Windows XP Visual Stuido.NET이 나온지 8,9년이 되었습니다. 시간이 흐른 만큼 OS나 개발툴에 변화가 생겼습니다. 특히 Windows 7이 나오면서 OS에 병렬 프로그래밍과 관련된 어떤 변화가 있었는지 이야기 합니다.

 

4. Concurrency Runtime

Concurrency Runtime의 전체 구조에 대해서 설명합니다.

 

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

Concurrency Runtime의 일부인 PPL에 대해서 어떤 것인지, 어떻게 사용하는지 설명합니다.

 

 

 

세미나 관계자 이야기로는 현재 세미나 등록한 인원이 많다고 합니다. 제 생각에 새로운 VS 툴이나왔고 C++ 관련 세미나는 워낙 없기도 해서 세미나에 오시는 분들이 많지 않을까 생각합니다. 사람이 많이 오니 가급적 빨리 와서 좋은 자리를 잡아서 편안하게 강연을 듣기를 바랍니다.^^

 

 

 

https://msevents.microsoft.com/cui/EventDetail.aspx?culture=ko-KR&EventID=1032447922&IO=jgXfPOVLFvgCqIHn3by1Uw==




ps : 확실한 것은 아니지만 아마 15일에 오시면 "First Look C++"이라는 작은 책자를 받을 수도 있을겁니다.

이 책자는 제가 VSTS2010 팀블로그에 올린 C++0x 관련 글을 정리한 책자입니다. 블로그에 올린 글을

기본으로 잡았지만 RValue Reference와 lambda는 다시 적었습니다.

저작자 표시
신고
by 흥배 2010.04.14 00:30

오늘 RC 버전이 나와서 저처럼 Beta 버전 사용하는 분들은 지우고 RC를 설치하기 위해서 Beta 버전을 확실하게 지워야 합니다.

 

확실하게 지우는 방법은 아래처럼 하면 된다고 합니다.

  1. Visual Studio 2010 Ultimate beta/beta2/RC를 언 인스톨한다.
  2. Visual Studio 2010 Tools for Office Runtime 를 언 인스톨한다.
  3. .NET Framework 4 beta/beta2/RC를 아래 순서대로 언 인스톨한다.
    1. Language Pack
    2. Extended
    3. Client

 

출처 : http://blogs.msdn.com/masaki/archive/2010/02/09/visual-studio-2010-beta-uninstall.aspx

 

저작자 표시
신고
by 흥배 2010.02.09 19:04

Window7 의 새로운 API Direct2D라는 것이 있습니다. 이것은 DirectX2D 기능을 Win32 API로 사용할 수 있는 것입니다.

 

저는 가장 최신의 Windows SDK설치 후 Visual Studio 2010 Beta1에서 Direct2D 예제를 빌드 해보니 빌드는 아주 잘 되었으나 실행이 제대로 되지 않았습니다.

이유는 D2D1CreateFactory 함수에서 에러가 발생했기 때문입니다. 에러는 I_GNOINTERFACE 였습니다. 처음에는 이유를 모라서 헤맸는데 검색을 해보니 인터페이스의 버전이 틀렸기 때문이었습니다.

 

제 PC에는 Windows SDK가 6.0A, 7.0, 7.0A 이렇게 총 3개가 설치 되어있어서 lib 파일과 헤더 파일의 버전이 서로 다르게 링킹 되었던 것 같더군요.

그래서 수동으로 lib 파일과 헤더 파일을 7.0으로 맞추니 문제 없이 실행 되었습니다.

 

Direct2D의 D2D1CreateFactory에서 실패가 발생하는 분들은 헤더 파일과 lib 파일의 디렉터리를 같은 SDK 디렉터리로 맞추면 아마 문제가 없을 것입니다.

저작자 표시
신고
by 흥배 2009.09.21 01:59

[CEDEC 2009]MS의 카와니시 히로유키씨가 차기 개발툴 「Visual Studio 10」의 병렬화 지원 기능을 소개


이미, 멀티 코어 프로세서는 가격적으로도 특별한 것은 아니다. 사진은 Phenom II X4 965 Black Edition/3.4GHz」

PC의 세계에서도 또 컨슈머(consumer) 게임기의 세계에서도 멀티 코어 프로세서가 급속히 퍼지고 있다. 싱글 코어로의 성능이 향상하던 시대라면 프로그래머가 가만히 있어도 하드웨어가 새로워지면 프로그램의 고속화를 기대할 수 있었지만 멀티 코어 시대는 그렇지 않다.
 

프로세서 전체의 퍼포먼스는 오르고 있어도 코어 하나 정도의 성능이 오르고 있다고는 할 수 없기 때문에 아무것도 생각하지 않은 프로그램은 전혀 성능이 오르지 않는 상황이 되고 있어 프로그래머 측에도 노력이 요구되고 있는 것이다. 많이 알려진 “프로그램의 병렬화”(자주 말하는 multi-thread 화와 거의 동의)이다.
 

게임은 비교적 multi-thread화가 어려운 소프트웨어로 4Gamer에 게재되는 각종 benchmark test 결과에서도 멀티 코어로의 성장이 적은 현실에 그것이 잘 나타나고 있다고 말할 수 있을 것이다.
 

그렇다고는 해도 멀티 코어화의 흐름 거술러 수는 없는 것으로 게임도 CPU 코어 수에 따라 확정성 높게 퍼포먼스를 늘릴 수 있는 병렬화의 궁리가 필수가 되고 있는 것도 확실하다.
 

CEDEC 2009의 2일 째에 행해졌던「측정할 수 있는 병렬화」라고 제목이 된 세션은 차기 개발툴「Microsoft Visual Studio 2010」(이하 Visual Studio 2010)가 지원 하는 병렬화 지원의 소개를 중심으로 병렬화의 포인트를 설명 하는 내용이었다. 게임에 특화한 이야기는 적고 또 프로그래머 전용의 세션인 만큼 게이머에게 직접 관계가 있는 이야기는 아니지만 툴의 지원이 충실하는 것으로써 게임의 병렬화도 진행되지 않을까라고 기대하면서 내용을 소개해 본다.



프로그램의 병렬화에 가로막는 다양한 곤란

 

마이크로소프트 디벨로퍼&플랫폼 통괄 본부 플랫폼 선교자 카와니시 히로유키씨

본세션을 담당한 것은 Microsoft의 일본 법인인 마이크로소프트에서 플랫폼 선교자를 맡은 카와니시 히로유키씨다. 마이크로소프트가 담당하는 기술 세션에서는 친숙한 「얼굴」이다. 아시는 분도 많다고 생각하지만 카와니시씨가 자랑으로 여기는 것은 그래픽스. 그 때문에 이 세션도 「뒤의 타이틀은「Larrabee」(라라비, 개발 코드네임)의 준비를 하자, 차세대 준비를 하려는 김」으로 할까라고 생각하고 있었다고 한다.
 

카와니시씨는 우선 CEDEC 2009에서 행해졌던 CrytekCarl Jones씨에 의한 세션에서 다루어지고 있었다고 하는 예측을 소개. 그것은 2013년 이후 CPU, GPU 함께 고도로 병렬화 해 경합 하게 될 것이다 라고 하는 내용이다.
 

카와니시씨는 여기서 고도로 병렬화한 CPU나 GPU에 대응하는 「새로운 렌더링 알고리즘이 요구된다」라고 말한다. 그것이 어떤 것이 될까는 모른다고 하면서 「Direct3D 패러렐과 같은 것이 나올지도 모른다」라고 예측하고 있었다.또 그렇게 멀지 않은 장래 등장할 Larrabee에 대해서도 「범용적인 알고리즘이 예를 들면 32기의 CPU로 움직이는 것이 실현된다」라고도 말하고 있었다.


Crytek의 Carl Jones씨가 말하고 있었다고 하는 병렬화의 예측. 2013년 이후 CPU와 GPU는 고도로 병렬화해 새로운 패러다임(paradigm)가 요구되게 된다고 한다

 

카와니시씨는 Larrabee 대단히 기대하고 있는 것 같다. Larrabee는 범용적인 Pentium 클래스의 CPU 코어를 다수 집적한 프로세서로 GPU과는 달리 범용적인 알고리즘을 메니 코어로 처리할 수 있다

 

병렬화에 가로막는 다양한 장매물. 섬세하게 설명은 하지 않지만 무엇을 병렬로 하는가 하는 설계 상의 난관에 더해 스렛드 간의 동기, 데드 락이라고 하는 기술상의 문제나 에러로부터의 회복이나 디버그가 어려운 점 등 처음부터 마지막까지 병렬화에는 다양한 난관이 기다리고 있다

 

장래적으로는 32 CPU, 64 CPU……라고 하는 메니 코어로 프로그램을 동작시킬 필요가 있어 프로그램의 측정할 수 있는 병렬화는 급무가 되고 있는 것이다. 하지만 병렬화는 그렇게 간단한 물건은 아니다.
 

현재 유감스럽지만 자동적으로 프로그램을 병렬로 해 주는 「자동 병렬화 컴파일러는 없다」(카와니시씨). 따라서 병렬화는 프로그래머가 스스로 실시하지 않을 수 없지만 거기에는 다양한 곤란이 있다고 하며 나타난 것이 오른쪽의 슬라이드다.이러한 곤란을 어느 정도 클리어로 해 주는(≒해결해 준다)  “영리한 개발툴”이 요구된다고 지적한다.



Visual Studio 2010에 들어간 병렬화를 지원하는 기능

 

Visual Studio 2010에 구현되고 있는 태스크 스케쥴러. 여기서 말하는 태스크는 「병렬로 실행시키고 싶은 일」이라고 이해해 주었으면 한다. 프로그램측이 태스크 스케쥴러에 태스크를 건네주면 그것을 적절한 타이밍에 스레드로서 Windows에 실행시킨다고 하는 이미지다

 

베타인 Windows프 로그래밍에서는 병렬화할 수 있는 처리를 스레드로 구현하고 Windows API를 사용해 스레드를 기동시킨다라고 하는 일을 실시한다.
 

기동된 스레드는 Windows 커널의 스케쥴러가 적당한 CPU에 할당해 주지만 스레드를 처리시키는 차례 등은 프로그래머 스스로가 결정할 필요가 있다. 차례의 사정으로 놀고 있던 CPU가 나와 버리는 것은 바람직하지 않지만--CPU 수에 따라 성능을 올리고 싶으면 놀고 있는 CPU는 가능한 한 줄이고 싶다--, CPU를 효율적으로 일하게 하는 것은 꽤 어렵다고 하는 문제가 있다.
 

거기서 Visual Studio 10의 런타임에는「유저 모드 스케쥴러」라는 것이 구현되어 있다고 한다.
 

유저 모드 스케쥴러는 프로그램측에서 건네받은 태스크를 적절한 타이밍(=CPU가 보다 효율 좋게 일하는 타이밍)으로 태스크를 Windows의 스레드로서 실행시키는 기능을 가지고 있다.
 

예를 들면 「가능한 한 캐쉬가 두꺼운 태스크를 스케줄 한다」(카와니시씨)라고 한 것까지 자동적으로 해 준다라는 것.  「캐쉬가 두꺼운 태스크」라고 하는 것은 「캐쉬가 히트 하고 있을 태스크」라고 하는 의미이지만 유저 모드 스케쥴러의 자원 매니저는 PC에 탑재되고 있는 CPU 코어 수등을 파악하고 있어 기동하는 스레드의 수를 CPU 코어 수에 따라 조절한다고 하는 것도 자동적으로 행해진다라는 것이다.
 

여기서 데먼스트레이션을 했다. 그 내용은 아래에 게재한 사진으로 확인해 주었으면 한다.



 

바이너리 트리의 탐색을 재귀적으로 실시하는 C#의 데모 프로그램. 단순하게 스레드화 하면 ,500 이상의 스레드가 일어선다

 

메모장에 쓰여진 「17670」은 싱글스 레드로의 실행 시간(17.670초)로 「16866」은 multi-thread화 했을 때의 실행 시간(16.866초). 거의 변하지 않는 것은 4 코어의 플랫폼에서 500 이상의  스레드를 동시에 기동시켰기 때문이다.스레드 수가 너무 많아서 콘텍스트 스위칭이나 메모리 확보 등의 오버헤드가 커져 멀티 코어의 메리트를 살릴 수 없다

 

스레드 대신에 Visual Studio 10의 태스크로서 기동시키도록 고쳐 쓴다

 

그러면 불과 6초만으로 같은 처리가 종료했다.유저 모드 스케쥴러가 CPU 코어 수에 응한 태스크를 기동시켰기 때문이다

 



parallel_for 이용 예이지만 실제로는 정상적으로 동작하지 않는다. 병렬화 된 for문장 중에서 변수 u,v가 변화하기 때문이다. 이와 같이 스레드간에 공용되는 데이터가 있는 케이스에서는 단순하게 for 문장을 parallel_for로 옮겨놓을 수 없다

 

이 바이너리 트리의 데모는 약간 극단적이기는 하지만 유저 모드 스케쥴러의 효과를 매우 잘 아는 예다. 프로그래머는 플랫폼에 탑재되고 있는 CPU 코어 수를 의식할 필요는 없이 병렬화 할 수 있는 부분을 태스크로서 건네주는 것만으로 적당한 스레드로서 실행해 주는 모습을 알 수 있다.
 

또, Visual Studio 2010에는 병렬화를 지원하는 라이브러리 세트가 들어가 있어 루프를 병렬화한 parallel_for(for 문장을 병렬에 열린다), parallel_foreach(foreach를 병렬에 열린다)라고 하는 구조를 이용할 수 있는 것 같다.

....... 이하는 생략합니다.


 

 

출처 : http://www.4gamer.net/games/032/G003263/20090903008/

 

이 글은 스프링노트에서 작성되었습니다.

신고
by 흥배 2009.09.17 01:06

VSTS 2010 VC++ 10의 큰 핵심 feature 두 가지를 뽑으라고 하면 저는 C++0x와 Concurrency Runtime 두 가지를 뽑고 싶습니다.

VC++ 10
은 시대의 변화에 맞추어 새로운 C++ 표준과 병렬 프로그래밍을 받아들였습니다.

현재도 Win32 API에 있는 Thread  관련 API를 사용하여 병렬 프로그래밍을 할수 있습니다. 하지만 이것만으로 병렬 프로그래밍을 하기에는 너무 불편합니다.
그래서 VC++ 10에는 Concurrency Runtime 이라는 것이 생겼습니다.



Concurrency
Parallel의 차이


........................


나머지는 여기에서 봐 주세요^^

저작자 표시
신고
by 흥배 2009.07.30 18:02

클로져 사용하기 2

 

<Code 4> 에서는(세 번째 글의 마지막 예제) 하나의 변수만을 캡쳐했지만 복수의 변수를 캡쳐하는 것도 가능할까요? 네 당연히 가능합니다.


‘[]’ 사이에 캡쳐할 변수를 선언하면 됩니다.

[ &Numb1, &Numb2 ]

 

그럼 ‘[&]’로 하면 어떻게 될까요? 이렇게 하면 람다 식을 정의한 범위 내에 있는 모든 변수를 캡쳐할 수 있습니다.


............ 나머지 글은 여기에서 보세요^^;





저작자 표시
신고
by 흥배 2009.06.24 01:09

C++에서의 람다 사용 법

 

람다 사용 방법은 아래와 같습니다.

[](파라메터) { }

 

int 값에 50을 더한 후 반환하는 람다 함수 

[](int x) { return x + 50; }

 

위 방법은 반환 값의 type“x+ 50”의 값의 type으로 추정되어 반환됩니다.

만약 반환 값 type을 지정하고 싶다면

 

[](int x) -> int { return x + 50; }

라고 하면 됩니다. 그리고 참고로 반환하지 않을 것이면 반환하지 않아도 됩니다.

또한 클로져를 사용하면 “[]” 사이에 참조를 넘길 수도 있습니다.

 

그럼 람다 사용 방법을 좀 더 알기 쉽도록 여러 가지 사용 예를 보여 드리겠습니다.



....... 나머지는 여기서 봐 주세요 ^^;

저작자 표시
신고
by 흥배 2009.06.10 00:13

이번은 C++0x에서의 새로운 기능 중의 하나인 Lambda에서 대해서 설명하겠습니다.

C#이나 동적 프로그래밍 언어를 공부 하신 분들은 Lambda에 대해서 들어보셨을 것입니다.

 

람다를 잘 모르는 분들을 위해서 현재 가장 쉽게 Lambda를 접할 수 있는 C#을 통해서 Lambda 사용 예를 들어보겠습니다.

(C#을 모르고 C++만 아는 분들이라도 무리 없이 볼 수 있으니 그냥 넘어가지 마시고 봐 주세요. C# 이야기는 조금만 할께요^^)

 

 

 

C#에서의 람다 식

 

람다 식은 식과 문을 포함하여 대리자나 식 트리 형식을 만드는데 사용할 수 있는 익명함수입니다.

 

형식은 다음과 같습니다.  

입력 매개 변수 => or

 

람다 식은 주로 어떤 라이브러리의 식과 결합해서 사용할 식을 만들 때 사용합니다.

람다 식이 없다면 다른 식과 결합하기 위해서는 따로 함수를 만들어서 사용해야 되므로 거추장스러워 지는데 람다 식을 사용하면 아주 간단하게 구현할 수 있습니다.

 

< Code 1. C# - 이름 중 문자 길이가 TextLength 보다 작은 이름 >

string[] MobNames = { "Babo", "Cat", "Orge", "Tester", "CEO" };

int TextLength = 4;

           

// 람다 식 사용

var ShortNames1 = MobNames.Where(MobName => MobName.Length < TextLength);

 

// foreach 사용

List<string> ShortNames2 = new List<string>();

foreach(string MobName in MobNames)

{

     if (MobName.Length < TextLength)

     {

         ShortNames2.Add(MobName);

     }

}

 

<Code 1>을 보면 람다 식을 사용하면 한 줄로 끝나는 것을 람다 식을 사용하지 않으면 List 컨테이너를 생성하고 foreach 구문을 사용하여 이름을 하나씩 조사하여 List 컨테이너에 추가해야 되는 코드가 필요해집니다.

 

C#에서 람다 식이 가장 유용하게 사용되는 부분은 Linq 일겁니다.

만약 Linq에서 람다 식을 사용하지 않게 된다면…Linq 사용하기가 꽤 힘들어지겠죠

 

 

 

C++에서 STL 알고리즘을 사용했던 불편했던 것
..................


나머지는
여기서 봐 주세요^^

저작자 표시
신고
by 흥배 2009.06.03 15:51

RValue Reference에 관한 글의 마지막으로 Perfect Forwarding에 대해서 설명합니다.

 

 

인수 전달 문제

 

< Code 1. >

void inner(int& i)

{

}

 

template <typename T> void outer(T& t) {

           inner(t);

}

 

 

int main()

{

           int a = 5;

           outer(a);

 

           outer(6);

           return 0;

}


<Code 1>을 컴파일 하면 outer(6)에서 컴파일 에러가 발생합니다.

error C2664: 'outer' : cannot convert parameter 1 from 'int' to 'int &'라는 에러 결과가 출력됩니다. <Code 1>을 컴파일 하기 위해서 파라메터에 const를 포함하는 함수를 재정의 해야 합니다.

 

...........나머지 글은 여기에서 봐 주세요^^;

저작자 표시
신고
by 흥배 2009.05.27 01:15

이번 회는 Move 생성자와 Move 대입 연산자를 정의 했을 때 어떤 결과가 나오는지, 그리고 std::move 라는 것에 대해서 이야기 하겠습니다.



복사 생성자와 대입 연산자만 정의했을 때

 

< Code 1. 복사 생성자와 대입 연산자 정의 >

class NPC

{ 

public:

           int NPCCode;

          string Name;

 

           NPC()

           {

                     cout << "기본 생성자" << endl;

           }

 

           NPC( int _NpcCode, string _Name )

           {

                     cout << "인자가 있는 생성자" << endl;

           }

 

           NPC(NPC& other)

           {

                     cout << "복사 생성자" << endl;

           }

 

           NPC& operator=(const NPC& npc)

           {

               cout << "대입 연산자" << endl;

               return *this;

           }

};

 

int main()

{

           NPC npc1( NPC( 10,"Orge1") );

          

           NPC npc2(11,"Orge2");

           NPC npc3 = npc2;

          

           NPC npc4;

           NPC npc5;

           npc5 = npc4;

 

           return 0;

}

 

< 결과 >


당연한 결과가 나왔죠^^

 

그럼 <Code 1> Move 생성자와 Move 대입 연산자를 정의하고 결과를 보겠습니다.

 

 

Move 생성자와 Move 대입 연산자 정의

.......
.......
나머지는
여기에서 봐 주세요^^

저작자 표시
신고
by 흥배 2009.05.10 02:55
| 1 2 |

티스토리 툴바