저희 Viva 2010 팀은 차세대 개발 플랫폼인 Visual Studio 2010, Visual Studio Team System 2010, C# 4.0, C++ 0x, Cloud 등을 공부하고 다양한 매체를 통해 알리는 팀 입니다.

저희 VSTS 2010 팀은 최근 Visual Studio 2010 베타 2 공개와 앞으로 곧 나오게 될 RC 및 정식 버전 출시에 발 맞춰서 활동을 더욱 강화하기 위해서 팀 멤버를 추가로 모집하고 있습니다.


그간의 활동

온라인 활동

http://vsts2010.net 블로그를 통해서 총 164개의 Article 발행, 총 방문자 약 50000, 일 평균 300명의 방문


오프라인 활동


[2009년 6월 10일 MSDN 주간 세미나]

강보람 - C#연대기 -C#의 Before/After

공성의 - VSTS2010에서의 소프트웨어 품질 관리

김병진 - VSTS 2010 Architecture & UML

엄준일 - Managed Extensibility Framework

최흥배 - Visual C++ 10, C++0x 그리고 Concurrency Runtime


[TechDays 2009 참여]

김병진, 강성재 - Visual Studio Team System 2010 Overview

최흥배새로운 시대를 여는 Visual C++ 10

강보람C# 4.0 with dynamic : 사랑과 전쟁. 그들의 4주 후…

조진현Multi-threaded rendering in DirectX11

엄준일, 공성의Visual Studio Team System 2010 With Agile

김대욱, 김태균WPF4.0 을 위한 VIsualStudio 2010



활동 영역

온라인 활동 영역

팀 블로그 활동

팀 블로그를 통해 자신의 글을 게시할 수 있습니다. 현재 수백 명의 정기 구독자에게 글이 공개가 되며, 팀 블로그가 구글 등의 검색 상위권에 이르게 됨으로 자신의 글이 상위 검색에 노출되는 간접적인 혜택을 누릴 수 있습니다.

온라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 여러 가지 온라인 세미나의 스피커로 활동하게 됩니다.

온라인 커뮤니티(예정)

온라인 커뮤니티 활동과 함께 커뮤니티 운영 활동을 하게 됩니다.

   

오프라인 활동 영역

오프라인 스터디

오프라인 스터디를 통해 자신의 분야를 공부하고 발표합니다. 그리고 좋은 콘텐츠는 곧바로 온라인/오프라인 세미나 스피커 활동으로 이어집니다.

오프라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 오프라인 세미나의 스피커로 활동할 수 있습니다. 팀 자체에서는 매월 오프라인 정기 세미나를 진행하며, 자신의 노하우를 오프라인 세미나를 통해 전달할 수 있는 기회를 드립니다.

기고

팀 블로그를 통해 축적된 자신의 콘텐츠는 월간 잡지 등에 기고할 수 있습니다.

책 집필, 번역(예정)

다양한 노하우를 책으로 집필하고, 외국의 유명 서적을 번역하는 활동을 계획하고 있습니다.

Microsoft MVP 추천

MVP 에 되고자 하시는 분은 한국 이크로소프트 직원과 마이크로소프트 MVP 의 추천을 드립니다.

   

모집 분야

  • Cloud Development
  • C#
  • VB.NET
  • C++
  • Agile Development
  • Parallel Development
  • Web Development
  • ASP.NET
  • Silverlight
  • Windows 7 Development
  • RIA Development
  • Architect Development
  • Office Business Application Development
  • .NET Framework 4.0
  • Visual Studio 2010
  • Visual Studio Team System 2010
  • ETC…

   

마감

정해진 마감 일자는 없습니다만, 적어도 12월 중에는 저희와 함께 할 수 있었으면 합니다. 가능한 빨리 지원해주시길 부탁드립니다.

   

지원 방법

아래의 양식을 채워주시고 kkongchi@gmail.com 으로 보내주세요.

이름

  

사진

  

블로그

  

전화번호, 이메일

  

티스토리 아이디

  

소개

(직업 및 회사명 포함)

관심 분야

(중복 가능)

   

지원해 주신 내용에 대한 심사 후, 오프라인 인터뷰를 통해서 멤버를 선정하게 됩니다. 이번에는 특히 활발한 온라인 활동, 특히 개인 블로그 활동을 많이 해오신 분들을 우선적으로 선정할 예정입니다.

   

지원 시 유의 사항

참고로 저희 스터디에서는 배우고자 지원하시는 분들은 선발하지 않습니다. 저희 팀의 스터디에서는 여러분들에게 아무것도 가르쳐주지 않습니다.

저희 팀에서는 절대 실력을 보고 맴버를 선발하지 않습니다. 물론 실력이 출중하면 좋겠지만 새로운 VSTS 2010 분야는 어느 누구도 밟아보지 않은 새로운 황야와 같습니다. 새로운 길을 함께 가실 활동력이 충분하신 분들은 꼭 지원해 주시기 바랍니다. ^^

[JumpToDX11-8] Deferred Contexts

DirectX 11 2009. 12. 2. 09:00 Posted by 알 수 없는 사용자

멀티스레드 기반의 렌더링을 위해서 DirectX11 에서는 세가지를 중점에 두었습니다.

- 비동기적으로 자유스러운 리소스 로딩과 관리.
  ( 이들은 렌더링과 동시에 수행될 수 있어야 한다. )

- 멀티스레드 형식으로 렌더링 커맨드의 생성.
  ( 여러 스레드로 나누어서 렌더링 작업을 할 수 있어야 한다. )

- 디스플레이 리스트( Display lists )의 지원.


첫번째 리소스와 관련한 것을 지난 시간에 알아보았습니다.
이제는 실제 렌더링 작업에 대해 알아보아야 합니다.
그 실제 렌더링 작업을 위해서 우리는 새롭게 등장한 Deferred Context 라는 것을 살펴볼 것입니다.
Deferred Context 가 멀티스레드 기반의 렌더링에서 가장 중요한 키워드입니다.

< Device 의 분리 >
지난 세대의 DirectX는 모든 GPU 관련 내용의 처리는 Device 인터페이스를 통해서 수행했습니다.
즉 지난 회들에서 꾸준히 언급했던 것처럼,
Device 인터페이스를 통해서만 커맨드( Command ) 를 생성할 수 있었습니다.



오직 싱글코어 기반으로 설계된 지난 세대의 DirectX 였기 때문에,
위의 그림과 같은 상황이 연출되었습니다.
이들에 대한 내용은 지난 시간을 통해서 꾸준히 언급되었기 때문에, 더 자세한 언급은 하지 않겠습니다.

Device 인터페이스에 모든 작업이 집중되어 있었기 때문에,
이를 분리할 방법이 필요했습니다.
그 기준은 앞서 언급했듯이, 
그래픽카드에 보내는 작업이 Free threaded 한지였습니다.
결론적으로 얘기 드리면 DirectX11 에서는 기존의 Device 가 분리에 분리를 거듭했습니다.
그래서 아래와 같은 구조로 되었습니다.





DirectX11 에서 이제 개발자가 다루어야하는 커맨드 생성 인터페이스는 총 3가지입니다.
Device 는 Free threaded 한 API 만 사용하는 인터페이스입니다.
주로 리소스들이 포함됩니다.( 버퍼나 텍스쳐, 쉐이더 등 )

Device Context 는 실제로 렌더링과 관련된 인터페이스입니다.
렌더스테이트의 교체나 Draw 명령을 내리기 위해서는
반드시 Device Context 를 통해서 커맨드를 생성해야 합니다.
더 자세한 사항은
http://vsts2010.net/115 여기를 보시기 바랍니다.^^

Device Context 는 다시 두개로 분리될 수 있습니다.
Immediate Context 와 Deferred Context 가 바로 그것들입니다.

만약 멀티스레드 기반으로 렌더링 하고 싶지 않다면,
Deferred Context 는 사용하지 않으셔도 됩니다.
Deferred Context 의 유무가 바로 멀티스레드 기반의 렌더링이냐,
아니면 일반적인 렌더링이냐를 결정
합니다.
반면에 Immediate Context 는 반드시 한개만 존재해야 합니다.
이 인터페이스는 실제로 렌더링과 관련된 커맨드를 생성하기도 하지만,
생성된 커맨드를 그래픽 카드로 보내는 일
도 합니다.

< Deferred Context >

Deferred Context는 애플리케이션에서 여러개 생성될 수 있습니다.
하나의 스레드에 하나씩 Deferred Context 가 사용될 수 있으며, 이들은 Thread unsafe 합니다.
이렇게 하나의 스레드에 할당되어진 Deferred Context는 Display List 를 생성합니다.
이들은 GPU 가 바로 처리 가능한 커맨드들을 모아둔 버퍼라고 할 수 있습니다.
이렇게 Display List 를 미리 만들어둠으로써 성능을 크게 개선 시킬 수 있습니다.
일반적으로, CPU 가 커맨드를 생성시키는 시간이 꽤 오래 걸리기 때문입니다.
( 생성될 커맨드가 변화가 없다면, 이렇게 미리 만들어 두면 크게 도움이 되겠죠? ^^ )


사실 위의 그림은 개념적인 것입니다.
실제 소스레벨에서 Deferred Context 를 가리키는 인터페이스는 별도로 존재하지 않습니다.
Immediate Context 를 가리키는 인터페이스는 ID3D11DeviceContext 입니다.
Deferred Context 를 가리키는 인터페이스도 ID3D11DeviceContext 입니다.
즉, 둘 다 동일한 인터페이스를 통해서 처리되고 있는 것입니다.
실제 멤버 변수 선언들을 조금 나열해 보면 다음과 같습니다.

ID3D11Device*      m_ipGPU;
ID3D11DeviceContext*    m_ipImmediateContext;
ID3D11DeviceContext**  m_ippDeferredContextArray;

동일한 인터페이스 선언을 확인하셨습니까?
하지만 인터페이스가 동일하다고 해서, 이를 동일하게 생각해서는 안됩니다.
동일한 인터페이스를 사용하는 이유는
Deferred Context 는 Immediate Context 의 모든 기능을 지원한다는 의미로 받아들여야 합니다.
결과적으로 Device Context 는 아래의 그림과 같은 구조로 확장될 수 있습니다.




멀티스레드 기반으로 렌더링을 한다는 것은 엄밀히 말해서는 지원하지 않습니다.
정확히 말하자면, 멀티스레드 기반으로 커맨드를 생성해서
이들을 순차적으로 그래픽 카드로 보냅니다.

위의 그림이 이를 잘 표현하고 있습니다.

Deferred Context 는 각각의 스레드에 의해서 DisplayList 를 생성하고,
이들을 그래픽 카드에 보내기 위해 버퍼에 저장합니다.
그리고 실제로 그래픽카드에 커맨드를 보내기 위해서는
반드시 Immediate Context 를 통해야 합니다.
이때 Immediate Context 를 통해서 직접적으로 커맨드를 생성시킬 수 있습니다.

아무래도 렌더링이라는 작업은 순간순간의 렌더링 상태들에 의해서
결과가 변하기 때문에, 최종적으로 전송하는 작업만큼은 순차적으로 설계한 듯 합니다.
이로써 우리는 Deferred Context 를 사용할 준비가 되었습니다.^^



Welcome to dynamic C# 외전(2) - Generic Method.

C# 2009. 11. 30. 08:30 Posted by 알 수 없는 사용자

- 또 외전이군 ㅋ

오랜만의 포스팅이네요. 넵. 또 외전입니다-_-;;; 최근에 다른 일때문에 포스팅을 못하다가 어떤 계기가 생겨서 포스팅을 하게됐습니다. 음;; 제네릭 메서드를 사용해서 코딩할 일이 있었는데요, 갑자기 전에 어떻게 했는지 기억이 안나는거 있죠-_-. 그래서, 기억을 더듬고 검색해서 코딩을 했습니다. 그래서 저도 안까먹고, 혹시 이거때매 해매는 분들을 위해서 포스팅을 할까 합니다.

* 경고 : 늘 그렇지만 제가 하는 포스팅은 허접합니다. 왜냐면, 제가 허접하기 때문이죠. 포스팅의 허접함에 눈이 아프시다면, "Oh My Eyes!"를 한번 외치시고 뒤로가기 버튼을 활용하시면 직빵입니다. ㅋ OME는 스타에서만 나오는게 아니거등요.


- 제네릭?

넵. 제네릭은 불필요한 박싱/언박싱을 없애도록 도와준 고마운 기능입니다. C# 2.0에서 추가가 됐었죠. 내부적으로는 F#에서 유용하다고 검증이 돼서, C#에 추가하기로 결정을 했었다고 합니다. F#이 쫌 까칠하긴 해도, 파워풀 하거든요^^(까칠하다보니, F#이랑 쫌 잘지내보려고 데이트도 11번 정도 했지만 일단은 손 놨습니다. 상처받은 마음을 C#과 좀 달래려구요. 근데 요즘은 C#한테도 상처를....)

혹시 모르는 분들을 위해서 허접한 실력으로 부연설명을 드리자면요. 박싱(boxing)은 포장을 하는 거구요, 언박싱(unboxing)은 포장을 푸는겁니다. 즉, C#에는 크게 타입이 크게 두가지로 분류가 되는데요. 값형식(value type)과 참조형식(reference type)입니다. 값형식은 변수의 이름이 가리키는 곳에는 실제 값이 들어있고, 참조형식은 변수의 이름이 가리키는 곳에 실제값에 대한 참조가 있습니다. 즉, C에서의 포인터의 개념을 생각하시면 됩니다. 포인터는 실제값을 가지는게 아니라, 값이 있는 곳의 주소를 가지고 있는거니까요.

근데, 값형 타입이 닷넷의 최상위 타입인 object같은 참조형 타입과 같이 처리해야 되는 경우가 있습니다. 예를 들면, C# 1.0에서는 컬렉션이 object형만 받을 수 있었습니다. 그래서, int타입만 처리하는 경우에도 컬렉션을 사용하려면, object타입으로 int타입을 포장해서 집어넣고, 빼낼때도 object타입의 포장을 풀고 int타입을 꺼내와야 했던거죠. 그런데, 이게 너무 삽질이다 보니 더 편하게 할 수 있는 방법으로 제네릭이 등장 했습니다.

제네릭은 어떤 타입도 될 수 있는 걸 말하는데요, List<int>는 int타입만 받는 컬렉션, List<string>은 string타입만 받는 컬렉션이 되면서, 불필요한 박싱/언박싱도 없어지고 코드도 훨씬 명확해 지는 장점이 있습니다. 그런데, 꼭 이럴때 뿐만 아니라도 제네릭이 필요한 경우가 생기는데요. 오늘 제가 설명드리면서 보여드릴 예제가 그런 경우입니다.


- 그래그래. 예제 내놔봐.

예제는 XML로 객체를 시리얼라이즈(Serialize)하고 다시 디시리얼라이즈(Deserialize)하는 건데요. 시리얼라이즈을 할때는 시리얼라이징 하는 객체의 타입을 명시해줘야 합니다. 그래서 한 프로그램에서 여러객체를 시리얼라이즈해야 할때는, 그 수만큼 오버로딩이 되기도 합니다. 하지만, 제네릭이 출동한다면?

제.

네.

릭.

...죄송합니다. 스덕이다 보니, 스타와 관련된 드립을 하게 되는군요. 계속해서 말씀드리죠-_-. 어떤 타입이든지 될 수 있는 제네릭을 활용한다면, 메서드를 변경시키지 않고서도 여러타입에 사용가능한 메서드를 만들 수 있습니다. 그럼, 소스를 한번 보시죠.

 class Serializer
{
    internal static bool Serialize<T>(T source, string fileName)
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            Stream stream = new FileStream(fileName, FileMode.Create,
                   FileAccess.Write, FileShare.None);
            serializer.Serialize(stream, source);
            stream.Close();

            return true;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    internal static T Deserialize<T>(string fileName) where T : class, new()
    {
        T target;
        FileInfo _settingFile = new FileInfo(fileName);
        if (!_settingFile.Exists)
        {
            return new T();
        }

        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            Stream stream = new FileStream(fileName, FileMode.Open,
                   FileAccess.Read, FileShare.None);
            target = serializer.Deserialize(stream) as T;
            stream.Close();

            return target;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}


위의 소스에서 <T>라고 쓰인부분이 바로 제네릭을 쓰겠다고 하는 겁니다. 즉, 어떤 타입이든지 될 수 있는 T라는 제네릭한 타입에 대해서 메서드를 작성하겠다는 거죠. 그리고 주목하실 부분이, Deserialize메서드 선언부의 끝부분의 "where T : class, new()"입니다. 이건, 제네릭한 타입 파라미터에 제약조건을 주는 겁니다. 즉, 위에 선언된 건 T가 제네릭한 타입이긴한데 class여야만 하고, 파라미터없고 public인 생성자가 있어야 한다는 겁니다. 그런 타입만 T를 통해서 넘어올 수 있다는 거죠. 제약조건은 그 외에도 아래와 같은 것들이 있습니다.

 제약조건  설명
 where T: struct  타입 매개변수는 반드시 Nullable을 제외한 값형(value type)이어야만 한다.
 where T : class  타입 매개변수는 반드시 참조형(reference type)이어야만 한다.
 where T : new()  타입 매개변수는 반드시 public이고 매개변수가 없는 생성자를 갖고 있어야 한다. 그리고 다른 제약 조건이랑 같이 사용될때는 new()가 맨뒤에 와야한다.
 where T : <base class name>  타입 매개변수는 반드시 명시된 클래스를 상속 해야한다.
 where T : <interface name>  타입 매개변수는 반드시 명시된 인터페이스이거나, 명시된 인터페이스를 구현해야 한다.
 where T : U  T에 해당되는 매개변수는 반드시 U에 해당되는 매개변수 타입이거나, U를 상속한 타입이어야 한다. 

네. 뭐 그렇답니다. 프레임워크 개발자나 복잡한 경우가 아니면, 저걸 다 쓸일이 있을지는 모르겠지만 알아두면 좋겠죠. 그리고 위의 코드는 아래와 같이 사용할 수 있습니다. 메서드가 static으로 된건 그냥 편의를 위해서 입니당.

public class Pair
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Program
{
    static bool SerializePairs(List<Pair> pairs)
    {
        try
        {
            Serializer.Serialize<List<Pair>>(pairs, "Pairs.xml");

            return true;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }

    static List<Pair> DeserializePairs()
    {
        try
        {
            return Serializer.Deserialize<List<Pair>>("Pairs.xml");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return new List<Pair>();
        }
    }

    static void Main(string[] args)
    {
        List<Pair> pairs = new List<Pair>
        {
            new Pair{
                Id=1,
                Name="홍길동"
            },
            new Pair{
                Id=2,
                Name="루저"
            },
            new Pair{
                Id=3,
                Name="위너"
            }
        };

        SerializePairs(pairs);
        List<Pair> pairs2 = DeserializePairs();

        foreach (Pair pair in pairs2)
        {
            Console.WriteLine(
                string.Format("{0} : {1}",
                    pair.Id,
                    pair.Name)
                );
        }
    }
}


Pair라는 객체가 있고, 그 객체에는 홍길동과 루저, 위너 이렇게 3명이 들어갑니다. 그리고 그 객체를 시리얼라이즈하고, 다시 디시리얼라이즈해서 결과를 화면에 출력하고 있죠. 메서드를 호출할때 "Serialize<List<Pair>>(pairs, "Pairs.xml")" 이렇게, <>안에 제네릭한 타입인 T가 실제로 어떤 타입이 될지를 명시해주고 있습니다. 그리고 결과를 보면 아래와 같구요.


넵. 그렇습니다. 별거 없죠-_-;;;


- 여기까지.

넵. 여기까지입니다. 뭐 특별한 내용도 없지만, 그냥 한번 정리하면 저도 편하고 필요하신 분들에게도 편하지 않을까 싶어서 말이죠-_- ㅋ. 소스는 파일로 첨부해드리겠습니다. 필요하신분들은 참고하시구요~. 언제가 될지는 모르겠지만, 다음 포스트에서 뵙져!!!


- 참고자료
1. http://msdn.microsoft.com/en-us/library/d5x73970.aspx