들어가기 앞서 지금까지 AMP가 GPU를 활용하는 프로그래밍 기법이라고, 제가 지속적으로 언급해 왔었습니다. 사실 이 말은 적절하지 않는 표현이였습니다.
얼마 전까지만 해도, 개발자에게 주어지는 프로세싱 유닛은 CPU와 GPU 뿐이였습니다. CPU는 개발자의 활용 영역에 있었지만, GPU는 제한적으로 사용할 수 있었습니다. 왜냐하면 GPU를 사용하기 위해서는 DirectX API 사용이 필수였기 때문입니다. 그 DirectX 의 영역을 일반적인 개발자 영역으로 확장하는 것이 C++ AMP 입니다. 그런데 최근에 CPU와 GPU를 통합한 APU 라는 것이 등장했습니다. 앞으로 또 다른 프로세싱 유닛이 등장할지도 모르는 일입니다. 그래서 이런 프로세싱 유닛들을 통합한 용어가 필요하게 되었고, C++ AMP에서는 이를 accelerator 라고 합니다. 즉, CPU와 GPU 그리고 APU 가 이 accelerator 에 속한다고 할 수 있습니다. accelerator 는 C++ AMP 코드가 실행될 수 있는 이런 타겟을 표현합니다. 그래서 C++ AMP는 이 accelerator를 활용하는 프로그래밍 기법이라고 해석하는 것이 더 적절한 표현입니다. 앞으로 이 accelerator 라는 표현을 많이 사용할 것이니 확실히 알아두시기 바랍니다.
앞서 간단하게 작성했던 샘플을 다시 한번 보겠습니다.
void AddArrays(int n, int * pA, int * pB, int * pC)
{
array_view<int,1> a(n, pA);
array_view<int,1> b(n, pB);
array_view<int,1> sum(n, pC);
parallel_for_each(
sum.grid,
[=](index<1> i) restrict(direct3d)
{
sum[i] = a[i] + b[i];
}
);
}
array_view 라는 것이 먼저 눈에 보입니다. C++ AMP 에서는 대규모 메모리를 의미하는 클래스로 array 와 array_view 라는 것이 있습니다. 기본적으로 이 두 클래스의 목적은 accelerator 상으로 데이터를 옮기기 위함 입니다.
array 의 경우에는 실제 데이터 배열입니다. STL 의 컨테이너와 유사합니다. 반면 array_view 는 데이터 배열의 일종의 래퍼( wrapper ) 입니다. 그래서 array_view 는 STL의 이터레이터( iterator ) 와 유사한 동작을 합니다. array_view는 한 번에 여러 데이터의 동시에 접근할 수 있으며, 랜덤 액세스( random-access ) 가 가능합니다.
array 에 의해서 정의되는 배열 데이터는 accelerator 상에 메모리를 가지게 됩니다. 이것은 개발자가 직접 정의해서 할당할 수도 있고, 런타임( runtime ) 에 의해서 자동적으로 생성될 수도 있습니다. 그렇기 때문에 실제 데이터가 생성되어질 때 깊은 복사( deep-copy )를 하게 됩니다. 우리가 일반적으로 오브젝트를 메모리에 생성했을 때와 같다고 생각하시면 됩니다.
array 는 다음과 같이 사용할 수 있습니다.( 샘플은 msdn 에서 가져왔습니다 )
data = a;
for (int i = 0; i < 5; i++)
{
cout << data[i] << "\n";
}
반면에 array_view는 이름에서 유추할 수 있듯이, 실제 데이터들은 다른 accelerator 상에 있고, 이를 연산을 위해서 복사를 하는 개념입니다. 즉, 커널 함수가 실행될 때, 데이터가 복사됩니다. ( 커널 함수는 AMP 내의 람다 함수 부분을 의미합니다. )
이 array_view 개념은 DirectX11 에서 보셨던 분들은 쉽게 이해할 수 있는 개념입니다. 바로 ComputeShader 를 위해서 데이터들을 연결하는 바로 그 개념이기 때문입니다. 아래의 그림은 ComputeShader 의 동작 방식을 보여주는데, SRV( shader resource view )와 UAV( unordered access view ) 라는 것이 결국 view 의 역할을 하는 것입니다.
DirectX11 과 연계해서 생각한다면, array 라는 메모리 배열도 결국 텍스쳐 메모리라는 것을 눈치챌 수 있을 것입니다. DirectX10 부터 텍스쳐 인터페이스는 꼭 이미지 데이터를 의미하지 않습니다. 대용량의 메모리 블럭의 의미에 더 가깝다는 것을 알아두시기 바랍니다. 텍스쳐의 개념을 사용하기 때문에 동시에 여러 데이터에 접근이 가능하고, 랜덤 액세스도 가능한 것입니다.^^
백문이 불여일견이라고들 하죠? 글로써 언급하는 것보다, 프로그래머들은 코드로 볼 때 더 직관적인 이해를 할 수 있는 경우가 많습니다.
간단하게 두 배열의 합을 구하는 코드를 통해서, 이를 AMP 적으로 어떻게 작성하는지를 보겠습니다.
아래는 우리가 일반적으로 생각할 수 있는 CPU를 활용해서 합을 구하는 코드입니다.
void AddArrays(int n, int * pA, int * pB, int * pC)
{
for (int i=0; i<n; i++)
{
pC[i] = pA[i] + pB[i];
}
}
자세한 설명은 생략해도 될 것이라 생각합니다.^^ 아래는 C++ AMP로 작성된 합을 구하는 코드입니다.
#include <amp.h>
using namespace concurrency;
void AddArrays(int n, int * pA, int * pB, int * pC)
{
array_view<int,1> a(n, pA);
array_view<int,1> b(n, pB);
array_view<int,1> sum(n, pC);
parallel_for_each(sum.grid,
[=](index<1> i) restrict(direct3d)
{
sum[i] = a[i] + b[i];
} );
}
위의 AMP 구현 부분에서 색상이 들어간 부분이 CPU를 활용한 부분과 다른 부분입니다. 코드량이 증가해버린 단순한 사실을 우리는 확인할 수 있습니다. 코드가 증가한 가장 기본적인 이유는 메모리 문제입니다. 우리가 지금까지 C++ 에서 사용하는 메모리는 CPU 가 접근할 수 있는 시스템 메모리입니다. 이 메모리를 GPU 로 처리하기 위해서는 GPU가 직접적으로 접근 가능해야 합니다. 그런데 C++ 에서 할당한 메모리는 GPU가 접근할 수가 없습니다. 그래서 비디오-메모리에 시스템-메모리의 데이터를 복사하는 과정이 필요합니다. 그 과정이 바로 코드의 증가를 불러오는 것입니다.
( 복사라고 보기는 조금 모호합니다만, 지금은 그냥 넘어가겠습니다. ) 이 증가한 코드들에 대해서 지금부터 살펴보겠습니다.
#include <amp.h>
using namespace concurrency;
AMP를 사용하기 위한 헤더의 선언입니다.
기본적으로 AMP를 사용하기 위해서는 람다식과 concurrency 에 대한 이해가 있어야 합니다.
array_view<int,1> a(n, pA);
array_view<int,1> b(n, pB);
array_view<int,1> sum(n, pC);
이 부분은 앞서 언급했던 GPU가 접근할 수 있는 메모리 영역으로 데이터를 만드는 부분입니다. 이 데이터를 만들 수 있는 메모리 영역이
array 와 array_view 라는 것으로 구분됩니다.
이 둘의 차이는 이후에 다루어 드릴테니,
지금은 GPU가 접근할 수 있는 메모리 영역으로 생각해 주셨으면 합니다.^^
parallel_for_each(... ) restrict( direct3d )
c++ 에 main(...) 이 있다면, AMP 에는 parallel_for_each( ... ) restrict( direct3d ) 가 있습니다. 이 부분은 GPU가 연산을 시작하는 진입점( EntryPoint ) 입니다. parallel_for_each를 잘 모르시는 분들은 아래의 링크를 참고하시 바랍니다. http://vsts2010.net/123 더 자세한 사항은 이 블로그의 VC++ 10 Concurrency Runtime 카테고리를 참고하시기 바랍니다.
제가 단순하게 정리해 드리면, 기존에 VC++ 10 에서 사용되는 parallel_for_each 는 CPU를 활용해서 병렬적으로 처리하는 것이지만,
뒤에 restrict( direct3d )를 명시함으로써 이를 GPU에서 병렬적으로 처리하도록 합니다. 이 진입 함수는 parallel_for_each( 람다식 ) 형태를 가지게 됩니다. 이는 GPU의 많은 스레드들에게 '이 람다식을 각각 실행해 주세요' 라고 명령을 내리는 것입니다. 역시 람다( Lambda ) 에 대해서 잘 모르시는 분은 옆의 카테고리에서 c++0x 를 보시기 바랍니다. 람다의 첫번째 설명 링크는 아래와 같습니다. http://vsts2010.net/73
그러면 얼마나 많은 스레드들이 람다식을 실행해야 하는지에 대한 명시가 있어야 합니다. 그것이 바로 paralle_for_each( ... ) 의 첫번째 인자인 sum.grid 입니다. grid 에 대한 설명은 뒷부분에서 자세히 다루겠으니, 지금은 스레드 갯수에 대한 정의로 보시면 충분합니다.
람다식의 인자로 index<1> idx 가 보이실 것입니다. 이 인자는 람다식에 전달되는 스레드들의 ID들입니다. 이 ID들을 통해서 스레들을 식별할 수 있습니다. 이 스레드들의 ID를 통해서 배열 형태의 데이터를 캡쳐해서 값을 저장하는 것입니다.
간단한 프로그램이지만, 사실 이런 형태가 C++ AMP의 전부입니다.^^
물론 이렇게 간단히 끝나면 무척 행복하겠지만, 난이도는 역시 알면 알수록 높아집니다.^^
본 글에서 사용된 예제들은 MS에서 사용된 예제들입니다.
제가 구현한 것들이 아님을 알려드립니다.^^
이 세가지를 처리하는 것이 디바이스-로스트 상황에 대처하는 것입니다. Direct2D 의 리소스와 관련한 내용은 http://vsts2010.net/593 글에서 제가 언급했었습니다.^^
그러면 하나씩 살펴보겠습니다. 우리가 진행했던 일반적인 렌더링 작업은 아래와 같습니다.
여기서 우리의 첫번째 단계를 처리합니다. 바로 hr = ::g_ipRT->EndDraw(); 부분입니다. EndDraw()는 렌더링 작업의 결과를 리턴합니다. 이 리턴 값이 D2DERR_RECREATE_TARGET 이면, 바로 디바이스-로스트 상황입니다. 이름에서 유추할 수 있듯이 "에러가 났으니, 다시 생성하라" 입니다.
이번에 제가 사용할 샘플은 바로 이전 시간에 했던 알파이미지를 렌더링하는 샘플입니다. 이 샘플에서 디바이스 의존적인 리소스는 렌더 타겟과 비트맵입니다. 즉 이 샘플에서 디바이스-로스트 상황이 발생한다면, 렌더타겟과 비트맵 리소스는 메모리에서 제거했다가 다시 생성해 주어야 합니다.
그래서 이번 샘플에서는 이들 리소스를 한번에 생성/삭제 하는 함수를 만들었습니다.
그리고 또 하나 고려해야 하는 부분이 있습니다. 바로 윈도우 사이즈의 변경입니다. 이 경우는 디바이스-로스트가 발생하지는 않습니다만, 순간적으로 화면이 깜빡이는 현상을 보이게 됩니다. 이 곳에도 역시 적절한(?) 처리를 해야 합니다.
렌더타겟의 리사이즈 작업이 실패하면, 역시 디바이스 의존적 리소스들을 모두 제거해 버립니다.
이제 WM_PAINT 이벤트를 위와 관련된 작업들과 연계해서 수정해야 합니다.
렌더타겟이 없는 경우는 디바이스-로스트 상황이거나 초기화 상태로 인식하고, 관련된 리소스를 생성합니다. 그리고 렌더타겟의 CheckWindowState()를 통해서 해당 윈도우가 가려져 있는지를 체크하고, 가려져 있지 않다면 렌더링 작업을 수행합니다.
렌더링 작업의 마지막에는 디바이시 로스트 상황을 체크해서 디바이스 의존적 리소스를 제거하고 있습니다. ( 앞서 언급했었죠..^^ )
이제 샘플이 약간은 안정성이 향상되었습니다.^^ 이상으로 디바이스-로스트와 관련한 작업을 마치겠습니다.^^
GPU를 활용하는 일은 모든 개발자에게 열려있는 길이여야 합니다. 하지만 DirectX를 직접적으로 활용해야만 하는 MS의 GPGPU 플랫폼인 DirectCompute는 그렇지가 않습니다.
그래픽카드라는게 원래 특수한 목적성을 가지고 등장한 장치이기 때문에, 이를 활용하는 사람들 또한 특정 영역에 국한되어 있는게 현실입니다. '이제부터 GPGPU 를 적극 활용합시다!' 라고 생각을 하더라도, 실제로 그것을 활용하기 위한 진입 장벽은 굉장히 높을 수 밖에 없습니다.
그러면 어떻게 해야만 이 장벽을 조금이라도 낮출 수 있을까요? 엔비디아의 CUDA 를 보면, 힌트가 있습니다. 하지만 몰라도 상관없습니다.^^ C++ 파일 내에서 컴파일러에 의해서 자동적으로 처리가 될 수 있으면 가장 좋지 않을까요? 순수 C++ 의 기능만 사용해서 컴파일러가 자동적으로 처리해 준다면, 개발자는 DirectX와 ComputeShader 에서 해방될 수 있을 것입니다. 그것이 바로 C++ AMP 가 등장하는 배경입니다. C++ AMP는 다음 버전의 VisualStudio 에 탑재 되어져서 등장할 예정이라고 합니다.
어떤 함수가 아래와 같이 있습니다. void Func( ... ) { 코드 } 위의 함수는 결국 컴파일러에 의해서 CPU 와 관련한 명령어를 생성하게 됩니다. 이를 AMP 적으로 확장하면 정확히 아래와 같이 구성됩니다. void Func( ... ) restrict( cpu ) { 코드 }
restrict 이라는 키워드를 함수에 적용함으로써 간단히 이를 구현합니다. 눈치가 좀 빠르신 분들이라면 '저 cpu를 gpu 로만 변경하면, gpu 로 컴파일 되어지는 것인가?' 라고 생각이 드실 겁니다. 네. 맞습니다. 그것이 바로 C++ AMP 가 DirectCompute 를 구현하는 방법입니다. 정확히는 아래와 같습니다. void Func( ... ) restrict( direct3d ) { 코드 } 'direct3d' 가 바로 'gpu' 를 의미합니다. 현재 이 옵션용 예약어는 확정적인 것은 아닙니다. 'direct3d' 가 확정될 수도 있고, 그렇지 않을 수도 있습니다. 아직 C++ AMP가 출시되지 않아서 유동적인 부분이 있습니다. 그 점 주의해서 읽어주시기 바랍니다.^^
다음 버전의 Visual C++ 부터는
함수마다 저렇게 restrict 한정자에 컴파일 옵션을 지정해주어야 합니다.
물론 지정을 하지 않았을 때는, 디폴트로 restrict( cpu ) 로 자동 처리할 것입니다.
그러면 한 함수 내에서 CPU와 GPU를 활용해야 하는 경우는 어떻게 해야할까요? void Func( ... ) restrict( direct3d, cpu ) { GPU를 사용하는 코드 CPU를 사용하는 코드 }
위와 같이 혼합해서 사용하는 것도 가능합니다.
또한 오버로드와 관련한 이슈도 문제 없이 처리될 것입니다. void Func( ... ); void Func( ... ) restrict( direct3d );
간단히 위와 같이 restrict 만으로 GPU를 사용하는 것이 완전히 된다면 얼마나 좋겠습니까만, restrict( direct3d ) 로 정의되어지는 함수들은 그에 상응하는 규칙으로 코딩 작업을
해야만 합니다.
이것이 사실 그렇게 쉬운 개념만으로 이해할 수 있는 것은 아닙니다.
하지만 DirectCompute를 직접 제어하는 것보다는 쉽습니다.
지금 D2D1을 공부중입니다.
혹시나 해서 질문을 올려보는데요.
RanderTarge->DrawBitmap();//해주고
RanderTarge->SetTransform();//을 해주면 비트맵이 변화가 되서 나옵니다. 그런데 이때 궁금 한점이 여러장의 비트맵을 생성했을 경우 DrawBitmap에는 각각의 비트맵을 선택해서 생성을 할수가 있는데 SetTransform은 일괄적으로 바껴버리네요 이걸 어떻게 해야하는건가요???
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
처음 Visual Studio 2010 릴리즈 되었을 때는 HTML5 기능이 추가가 되지 않았습니다. 그래서 XML Schema 를 이용하는 방법으로 HTML 텍스트 에디터에서 HTML5 구문을 사용하기도 하였습니다. 하지만 이번 Visual Studio 2010 SP1에는 정식으로 HTML5 인텔리센스와 유효성을 검사할 수 있는 기능이 추가가 되었습니다.
이 기능을 활성화하기 위해서 도구->옵션의 텍스트 에디터->HTML->유효성에서 HTML5 유효성 검사를 지정할 수 있습니다.
HTML5가 지원하는 여러 구문을 인텔리센스에서 자연스럽게 보여줍니다.
더불어 CSS3 를 완벽하게 지원하지는 않지만, 일부분 CSS3를 지원해 줍니다. CSS3 기능은 앞으로 그 기능을 보강할 수 있는 확장 기능으로 Visual Studio Gallery 에서 배포가 되길 기대해봅니다.
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
배포 가능한 종속성(Deployable Dependencies) 는 이번 Visual Studio 2010 SP1 에서 새롭게 추가된 기능입니다. 웹 응용 프로그램을 서버로 배포하기 위해서는 필수 구성 요소들이 설치가 되어 있어야 하는데, 배포 가능한 종속성 기능을 이용하면 웹 응용 프로그램이 동작에 필요한 일부 컴포넌트를 바로 배포할 수 있도록 도와줍니다.
웹 응용 프로그램에서 마우스 오른쪽 버튼을 클릭하여 컨텍스트 메뉴를 활성화하면 다음과 같은 메뉴 항목이 추가가 되어 있습니다.
메뉴 항목을 선택하면 아래와 같은 창이 나타납니다. 이 창에서는 ASP.NET MVC3 에서 사용하는 Razor 컴포넌트와 SQL Server Compact 를 선택할 수 있습니다.
위와 같이 배포 시 포함할 종속된 어셈블리/컴포넌트를 선택하여 확인 버튼을 클릭하면, 다음과 같이 웹 응용 프로그램 프로젝트에 _bin_deployableAssemblies 폴더가 생성이 되고, 이 하위에 관련된 어셈블리가 추가가 됩니다.
웹 응용 프로그램을 게시를 하게 되면, 위의 _bin_deployableAssemblies 폴더의 어셈블리는 웹 응용 프로그램의 bin 폴더로 배포가 됩니다.
물론, 웹 배포 패키지로 .ZIP 파일로 생성을 하여도 종속성을 추가한 어셈블리는 BIN 폴더에 추가가 되며, 이 패키지를 이용하여 배포할 서버에 컴포넌트의 설치 없이 바로 배포할 수 있습니다.
다만 현재는 여러 가지 배포 어셈블리/컴포넌트를 지원하지 않고 아래의 3개지의 컴포넌트만 배포를 지원해 줍니다.
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
앞에까지는 STL의 알고리즘에 추가된 것들을 다루었는데 이번에는
컨테이너 하나를 소개하겠습니다. 사실 이 컨테이너는 저도 얼마 전까지만 하더라도 새로 추가 된지 몰랐습니다.^^;
새로 추가된 컨테이너의 이름은 ‘forward_list’입니다.
이름을 들어보니 대충 어떤 컨테이너인지 감이 오시죠?^^ 네
이 컨테이너는 기존의 list 컨테이너와 비슷한 종류의 컨테이너입니다.
forward_list를 만든 이유
표준 라이브러리(STL)에는 이미 리스트(std::list) 라이브러리가 있습니다. 이것은 쌍 방향 리스트입니다. list는 사용하기는 편하지만 사용 메모리나 처리 속도에 조금 아쉬운 점이 있습니다. 또 대 부분의 상황에서 쌍 방향 리스트가 필요한 경우보다는 단 방향 리스트만으로 충분한 경우가 자주 있습니다. 이런 이유로 C++0x에서는 단 방향 리스트를 추가하기로 했습니다.
forward_list의 설계 방침
1. 특별한 이유가 없다면 forward_list는 기존의 list의 설계에 맞춘다.
2. 설계 상의 선택 기가 여러 개인 경우 성능(속도와 사이즈)을 최우선 한다(C의 구조체로 구현하는 경우와 비교하여 Zero Overhead로 한다).
3. std::list의
insert와 erase를 forward_list에서도
제공할 수 있지만 구현이 복잡해지고 성능 측면에서 좋지 않으므로 제공하지 않는다.
4. 다른 STL의 컨테이너들에 있는 size 함수를
제공하지 않는다. 이유는 요소 수를 보존하는 멤버를가지고 있으면 C언어에서
구현한 것과 비교해서 불필요한 메모리를 사용한다. 만약 이런 멤버를 가지고 있지 않으면서 size 함수를 지원하면 호출할 때마다 모든 요소를 세어야 하므로 계산량이 O(N)이
된다(그런데 유저는 다른 컨테이너와 같이 size의 계산량이
작을 것이라고 생각할 수 있다). 또 이미 unordered와
같은 연상 컨테이너도 기존의 요소를 만족하지 않고 있다.
STL의 list 컨테이너와 다른 점
forward_list는 기존의 list와 아래와 같은 점이 다릅니다.
1. forward_list는 단 방향 리스트(singly-linked-list)이다. 각 요소는 그 다음 요소를
가리키는 포인터를 하나만 가지고 있다(list은 양 방향 리스트).
2. (단 방향 리스트이므로)
list에 비해서 메모리를 작게 사용한다. 이것은 각 요소의 메모리만이 아닌 컨테이너 그
자체의 사이즈도 작다. int 형에 대해서 list는 12바이트라면 forward_list는 8바이트이다(64비트에서는 각각
24, 16).
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
기본적으로 웹 응용 프로그램을 개발할 경우 로컬에서 동작하는 ASP.NET Development Server 가 활성화가 됩니다.
그림 1 로컬 ASP.NET Development Server 가 동작하는 화면
웹을 개발할 때 Visual Studio가 제공하는 로컬에서 동작하는 ASP.NET Development Server 로 충분히 어려움 없이 개발을 할 수 있으나 웹 개발의 여러 가지 상황을 고려해 보면 기능이 충분하지는 않았습니다.
예를 들면, 기존의 로컬에서 동작하는 ASP.NET Development Server는 특정 웹 페이지나 XML 웹 서비스, WCF 서비스가 SSL(Secure Sockets Layer)로 동작한다거나 WCF의 NET.TCP, NET.PIPE 등의 바인딩을 사용할 수 없었습니다.
이런 여러 가지 기능적으로 IIS Express 를 사용할 경우 얻을 수 있는 이점이 많고, 기존 웹 응용 프로그램을 IIS Express에서 동작하도록 변경하기 위한 절차 또한 매우 간단합니다.
IIS Express가 설치되어 있다면, 웹 응용 프로그램에서 마우스 오른쪽 버튼을 클릭하여 IIS Express 사용을 선택하면 즉시 IIS Express 에서 웹 응용 프로그램이 동작하도록 할 수 있습니다.
그리고 다음의 확인 메시지에서 '예'를 클릭하면 바로 IIS Express로 웹 응용 프로그램을 개발할 수 있습니다.
IIS Express는 윈도우의 알림 영역에서 찾을 수 있으며 이 아이콘을 이용하여 여러 개의 호스팅 되고 있는 웹 응용 프로그램을 관리할 수 있습니다.
IIS Express를 사용하여 Visual Studio 2010에서 여러 가지 설정을 즉시 변경해 줄 수 있습니다.
그림 2 IIS Express 설치시 웹 응용 프로그램 속성
그림 3 기존 ASP.NET Development Server 속성
IIS 7과 IIS Express 버전의 비교표:
Area
IIS 7
IIS Express
Shipping mechanism
Ships with the OS.
Ships out-of-band. It is automatically included with WebMatrix but can also be installed separately.
Supported Windows editions
Limited number of Windows Vista and Windows 7 editions
Most editions of Windows Server 2003, 2008 and 2008 R2
All editions of Windows XP, Vista, Windows 7
All editions of Windows Server 2008 and 2008 R2
Supported .NET Framework versions
v2.0 SP1 and above
v2.0 SP1 and above (.NET 4.0 is required).
Supported programming languages
Classic ASP, ASP.NET, and PHP
Classic ASP, ASP.NET, and PHP
Process model
Windows Process Activation Service (WAS) automatically manages configured sites.
User launches and terminates sites.
Hosted WebCore (aka Hostable Web Core) support
Yes
Yes. IIS Express is implemented as a layer over HWC.
Supported protocols
HTTP, FTP, WebDAV, HTTPS, and WCF (including over TCP, Named Pipes, and MSMQ)
HTTP, HTTPS, and WCF over HTTP
Non-admin support
WAS must run with administrator user rights.
A standard user is allowed to complete most tasks.
Multi-developer support
None
Yes. Configuration files, settings, and Web content are maintained on a per-user basis.
Visual Studio support
Yes
VS 2010 SP1 Beta allows IIS Express to be used instead of Cassini. VS 2008 can also be manually configured to use IIS Express.
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
상관없이 판매하는 어떤 제품의, 그것이 흥미롭고 매력적인 외모면 더 많은 사람들이 그것을 사용하여 회사는 전문적이고 설득력보세요. 이 오해를 한 동안 그 많은 돈을 필요로 좋은 책자를 생산합니다. 지금은 훨씬 저렴합니다 홍보 자료의 작성을 만들 수 있습니다 우리 주변에 기술이 많습니다.
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
Visual Studio 2010 이전의 도움말 설명서(Help Documentation) 은 별도의 클라이언트 응용 프로그램으로 구동되었습니다. 하지만 Visual Studio 2010버전에서는 웹 브라우저를 통해 MSDN Online과 같은 화면으로 도움말 설명서가 로컬 웹 서버를 통해 구동이 되었습니다.
그림 1 Visual Studio 2008 도움말 설명서
그림 2 Visual Studio 2010 로컬 웹 도움말 설명서
두 가지 방식의 장단점은 다르겠지만, Visual Studio 2010 로컬 웹 도움말 설명서는 입력한 내용의 인덱스를 보여주지 않아 매우 불편했었습니다. 클래스 이름이나 네임스페이스 이름으로 검색할 때 AJAX 기술로 키워드의 인덱스를 보여주었더라면 그나마 좋았을 텐데 하고 불편함을 감수하기도 하였습니다.
Visual Studio 2010 SP1 에서는 로컬 웹이 구동되고 키워드가 인덱스 되지 않는 부분을 개선하여 기존의 로컬 도움말 설명서로 개선이 되었습니다.
그림 3 Visual Studio 2010 SP1 의 로컬 도움말 설명서
기존의 Visual Studio 2008 과 유사한 로컬 도움말 설명서 응용 프로그램으로 구동이 됩니다. 다만, 필자는 색인 창을 오른쪽에 도킹하여 쓰는데, 현재 Visual Studio 2010 SP1 에서는 도킹 기능은 제공하지 않습니다.
개선해야 할 점
기존의 웹 브라우저 방식보다 Help Viewer 1.1 이 낫긴 하지만, 여전히 사용자의 측면에서 불편하기는 마찬가지 입니다.
첫 번째, 여전히 로컬 웹 서버가 동작하여 도움말이 구동됩니다. 닫아버리고 싶은 왠지 모를 강박감…!
두 번째, 도움말의 폰트 크기가 제각각 입니다. 폰트도 작은데, 크게 키우면 너무 크고...
좌측은 Help Viewer 1.1, 우측은 MSDN 온라인 도움말.
세 번째, 샘플 코드 구조가 사정없이 깨집니다.
좌측, Help Viewer 1.1, 우측은 MSDN 온라인 도움말
네 번째, 개인적으로 인덱스 창을 오른쪽에 도킹하는데, 도킹 기능이 없네요^^;
다섯 번째, MSDN Documentation 2008 에서는 고유 URL 이 있는데, 지금은 도움말 에이전트의 URL 도 보여주지 않네요.
좌측은 MSDN Documentation 2008, 우측은 Help Viewer 1.1
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
"Visual Studio 응용프로그램모델링완전정복백서"는개발자에서더뛰어난개발자로안내하는효과적인백서입니다. 최종산출물인잘동작하는소스코드를위해, 모델링에대한배경과방법을개발자의관점에서설명합니다. 그리고 Visual Studio 2010를이용하여개발자가효과적으로모델링을할수있는환경을제시합니다.
개발자들이여, 이제는 "개발자는코드로말한다"는관념을버리십시오.현대의소프트웨어개발에서는언제까지당신의코드가나오기까지기다려주지않습니다.선택과집중의개발생태계에서당신이올바른방향을바라보고그첫발을내딛는다는것을아무도믿어주지않습니다.
ASP.NET 의가려운곳을긁어줄대안의프레임워크가나왔으니바로 ASP.NET MVC 프레임워크입니다. MVC 는각각담당하고있는일이있습니다. 컨트롤러는사용자요청의흐름을제어하고그에따른모델과뷰를선택하는일, 모델은데이터와유효성검사, 비즈니스로직을담당하는일, 뷰는컨트롤러에서전달받은데이터를 UI에서처리하는일을합니다. 이렇게모델, 뷰, 컨트롤러로명확하게분리된구조가여느복잡한어플리케이션도구조적으로좀더쉽게개발할수있도록도와줍니다. 여기백서를통해웹개발의도움을주는 M, V 그리고 C의각방생활을소개합니다.
두남자의 Visual Studio 2010 TDD(Test Driven Development)이야기
강보람 MVP (IT Flow 선임컨설턴트), 박세식 (유니위스) - 다운받기
TDD(Test Driven Development), 테스트주도개발은애자일한개발을지원하기위한하나의실천적도구입니다. 하지만, 단순히세부적으로어떻게해야되는것인지를묻는 'How'만으로는 TDD를제대로이해할수가없습니다. 어째서 TDD가소개되었으며, TDD를통해서어떤장점을얻을수있는지를이야기하는 'Why'와 'What'이동반되어야 TDD를이해할수있는기반을마련하는것이시죠. 여기두개발자가 TDD에대해나눈대화를흥미롭게재구성해기록한백서가있습니다. 이백서를통해서 TDD에대한 'Why', 'What' 그리고 Visual Studio 2010과웹개발에 TDD를적용한 'How'를같이얻으시기바랍니다.
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
이번에 설명할 is_partitioned, partition_point는 그 이름처럼 앞서 소개한 partition_copy와 관계가 있는 알고리즘 입니다.
is_partitioned의 원형
template<class InputIterator, class BinaryPredicate>
bool is_partitioned(
InputIterator _First,
InputIterator _Last,
BinaryPredicate _Comp
);
partition_point의 원형
template<class ForwardIterator, class Predicate>
ForwardIterator partition_point(
ForwardIterator _First,
ForwardIterator _Last,
Predicate _Comp
);
is_partitioned는 데이터셋의 요소가 전반 부와 후반 부 두 개로 나누어져 있는지 조사할 때 사용하고, partition_point는 두 개로 나누어져 있는 데이터셋에서 후반 부의 첫 번째 요소를 가리키는 반복자를 반환합니다.
약간 설명이 애매하죠?^^;
예를 들어 설명하면 온라인 FPS 게임에서 8명이 각각 4명씩 레드 팀과 블루 팀으로 나누어서 게임을 하는 경우 vector로 된 StagePlayers(온라인 게임에서 방에 들어온 유저들을 저장)에 앞 부분에는 레드 팀 플레이어 4명을 차례로 저장하고, 그 이후에 블루 팀 플레이어를 저장하고 있는지 조사하고 싶을 때 is_partitioned 알고리즘을 사용하면 알 수 있습니다(맞다면 true를 반환합니다). 그리고 StagePlayers에서 블루 팀의 첫 번째 플레이어에 접근하고 싶다면 partition_point를 사용합니다.
나름 쉽게 설명한다고 했는데 이해 가시나요? 만약 이해가 안 간다면 예제 코드를 봐 주세요^^
< 예제 >
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
struct PLAYER
{
int CharCD;
bool IsRedTeam;
};
int main()
{
vector< PLAYER > StagePlayers1;
PLAYER player1; player1.CharCD = 1;player1.IsRedTeam = true;StagePlayers1.push_back( player1 );
PLAYER player2; player2.CharCD = 2;player2.IsRedTeam = true;StagePlayers1.push_back( player2 );
PLAYER player3; player3.CharCD = 3;player3.IsRedTeam = true;StagePlayers1.push_back( player3 );
PLAYER player4; player4.CharCD = 4;player4.IsRedTeam = false;StagePlayers1.push_back( player4 );
PLAYER player5; player5.CharCD = 5;player5.IsRedTeam = false;StagePlayers1.push_back( player5 );
PLAYER player6; player6.CharCD = 6;player6.IsRedTeam = false;StagePlayers1.push_back( player6 );
PLAYER player7; player7.CharCD = 7;player7.IsRedTeam = false;StagePlayers1.push_back( player7 );
너무 멋져요을 개봉된! 나는 필자 전에 이런 걸 배우는 가정 없다. 그래서이 주제에 대한 몇 가지 참신한 아이디어가있는 모든 사람을 찾을 수 좋네요. 정말이 일을 시작 주셔서 감사합니다. 이 웹 사이트는 약간 독창성과 웹, 누군가에 원한의 한 가지입니다. 웹에 새로운 것을 가져다 유용 직업!
댓글을 달아 주세요
용량의 메모리 블럭의 의미에 더 가깝다는 것을 알