從 C++ 開發人員角度看 Metro Style App 開發上官林傑 (ericsk)Technical Evangelist
Microsoft
大綱• C++/CX 概論• 開發 Metro Style App• Win32 API 與 COM• 使用 AMP 透過 GPU 進行平行運算
用 C++ 的理由 (?)
• 只會寫 C/C++ (?)• 移植 C/C++-based library
– Using SQLite in a Metro Style App
• 為了更好的效能
Windows 8 開發平台
Metro style Apps
HTMLJavaScri
pt
CC++
C#VB
Desktop Apps
Win32
.NET / SL
Internet Explorer
Communication & Data
Application Model
Devices & Printing
WinRT APIs
Graphics & Media
Syst
em
Serv
ices
JavaScript(Chakra)
CC++
C#VB
XAML HTML / CSSVie
wM
odel
Contr
olle
r
Windows Core OS ServicesCore
Windows 8 開發平台細節
C++/CX
Metro Style App 用的 C++
• C++/CX (Component Extensions)• 用於 Metro Style App ( 以及 WinRT Component) 的
開發• 與 C++11 標準語法相容
– 可以使用 STL– 在 desktop app 開發中也可以使用 C++11 的語法
• 加入 C++/CLI 的語法– Reference count
• Platform 命名空間 (namespace)– 提供基礎資料結構 <collection.h>– 相容 WinRT
Metro Style App 程式碼片段// 建立 C++/CX 字串auto message = ref new Platform::String(L"Hello, world");// 建立訊息對話盒auto dialog = ref new Windows::UI::Popups::MessageDialog(message);// 顯示對話盒dialog->ShowAsync(); WinRT Component
C++/CX
C++11 語法範例IAsyncOperation<IMap<String^, Object^>^>^Class1::DoSomethingAsync(String^ uri, IMap<String^, Object^>^ parameters){ auto params = make_shared<MyParams>(); params->uri = uri->Data();
for_each(begin(parameters), end(parameters), [params](IKeyValuePair<String^, Object^>^ value) { params->parameters.push_back(tuple<wstring, wstring>(value->Key->Data(), value->Value->ToString()->Data())); });
....}
Type interface
lambda function
編譯 C++/CX
• 產生 native code– C++/CLI 產生執行於 CLI 上的 IL code , C++/CX 則是直接
產生機器碼• Power/Performance-efficiency
– 開發 metro style app 必須針對 x86, x64 以及 ARM 三種平台做 app package
開發 METRO STYLE APPS(WINRT)
XAML
• 宣告式 UI 框架<Button x:Name="MyButton" Width="80" Height="50" Content="Click" />
相當於 C++ 程式碼Button^ b = ref new Button();b->Name = L"MyButton";b->Width = 80;b->Height = 50;b->Content = L"Click";
• 可以用 Blend 或 VS Visual Designer 編輯• 與程式碼緊密結合
DEMO: METRO STYLE APP
WinRT Component 開發
• 加速或加密 Metro Style App 中的某部份– 不得已需要使用某些 Win32 API 或是 COM
• 透過「語言映射」 (Language Projection) 技術,讓以 C++/C#/VB.net 所開發出來的 WinRT component 得以讓各種語言寫的 metro style app 所使用– 針對不同平台都要 build 一份 .dll/.winmd 給 metro style app 用
WindowsRuntime
Object(or Component)
Writtenin C++, C#, VB
Windows Metadata
C++ App
Pro
jectio
n
CLR
C#/VB App
Pro
jec
tion
HTML App
Chakra
Pro
jectio
n
使用 Windows Runtime 範本#pragma once
namespace WindowsRuntimeComponent1{ public ref class Class1 sealed { public: Class1();
Platform::String^ SayHello() { auto hello = ref new Platform::String(L"Hello!"); return hello; } };}
實作 sealed 類別
Hybrid Metro Style App
• 在 Metro Style App 的專案中將這兩個檔案「加入參考」 (Add References)
• 接著就像使用 app 開發所使用的語言一樣呼叫 WinRT component API
取出 .dll 及 .winmd
// 就像在建立一個 JavaScript 物件var compo = new WindowsRuntimeComponent1.Class1();// 為 JavaScript 而將函式名轉成 camel case stylevar helloStr = compo.sayHello();
DEMO: WINRT COMPONENT
WIN32 API 以及 COM
使用 Win32 API 以及 COM
• 追求極致的效能• 移植過去的程式• 只有部份的 Win32 API 及 COM 可以在 Metro Style
App 中使用– WACK 可以協助確認是否可以用– 參考可以使用的列表 :
http://msdn.microsoft.com/en-us/library/windows/apps/br205753.aspx
– 或是看標頭檔是否有標示:#pragma region Application Family #pragma region Desktop Family
使用 COM
• 透過 Windows Runtime C++ Template Library (WRL) 來呼叫ComPtr<interface_name> ptr;HRESULT hr = CoCreateInstanceEx(CLSID_XXX...);if (FAILED(hr)) { // process error }
• 自己實作的 COM 物件必須實作 IInspectable 介面,並且由 Microsoft::WRL::Details::RuntimeClass 實作物件
• 除非有必要使用的 COM ,否則不建議這麼做
範例 : 使用 MSXML
// 實作 IXMLHttpRequest2Callback 介面class HttpRequestCallback : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IXMLHTTPRequest2Callback, FtmBase>{ ... // 實作收到回應的回呼函式 IFACEMETHODIMP OnResponseReceived(IXMLHTTPRequest2*, ISequentialStream* pResponseStream) { ... } ...}
範例 : 使用 MSXML ( 續 )// 使用 COMComPtr<IXMLHTTPRequest2> xhr;// 建立實體HRESULT hr = CoCreateInstance(CLSID_XmlHttpRequest, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&xhr));if (FAILED(hr)) { // 處理錯誤}// 建立 callback 實體auto callback = Make<HttpRequestCallback>(xhr.Get(), cancellationToken);...// 建立連線及設定 callbackhr = xhr->Open(method.c_str(), uri.c_str(), callback.Get(), nullptr, nullptr, nullptr, nullptr);...// 送出 requesthr = xhr->Send(nullptr, 0);
DEMO: 使用 MSXML6 COM
使用 AMP 做平行運算
AMP
• Accelerated Massive Parallelism– 相較於 PPL 是利用 CPU 做平行運算, AMP 用 GPU 平行運
算– 不一定只有 Metro Style App 可以用
• C++-style Library– 相較於其它的 GPU 加速程式碼– 加速 20 倍以上
• 函式庫– VS2012 導入,也包含在可散佈套件中– 規格是公開的
Ref:
使用 AMP
• #include <amp.h>• Namespace: concurrency• New classes:
– array, array_view– extent, index– accelerator, accelerator_view
• New function(s): parallel_for_each()• New (use of) keyword: restrict
– Asks compiler to check your code is ok for GPU (DirectX)
Array 相加範例void AddArrays(int n, int * pA, int * pB, int * pSum){ for (int i=0; i<n; i++) { pSum[i] = pA[i] + pB[i]; }}
#include <amp.h>using namespace concurrency;
void AddArrays(int n, int * pA, int * pB, int * pSum){ array_view<int,1> a(n, pA); array_view<int,1> b(n, pB); array_view<int,1> sum(n, pSum); parallel_for_each( sum.extent, [=](index<1> i) restrict(amp) { sum[i] = a[i] + b[i]; } );}
分析 AMP 程式碼
void AddArrays(int n, int * pA, int * pB, int * pSum){ array_view<int,1> a(n, pA); array_view<int,1> b(n, pB); array_view<int,1> sum(n, pSum); parallel_for_each(
sum.extent, [=](index<1> i) restrict(amp) { sum[i] = a[i] + b[i];
} );}
array_view 變數可以移到 GPU 來平行處理
restrict(amp): 問 compiler 是否可以使用 AMP 函式庫
parallel_for_each: 將 lambda 放在所有的 thread 上執行
extent: thread 間共用的物件
index: 用來辨別是哪一個 thread 執行
array_view: 將原本的陣列轉成可以 AMP 處理的資料結構
使用 AMP 的限制
• No – recursion– 'volatile'– virtual functions– pointers to
functions– pointers to member
functions– pointers in structs– pointers to pointers– bitfields
• No – goto or labeled
statements– throw, try, catch– globals or statics– dynamic_cast or typeid– asm declarations– varargs– unsupported types
• e.g. char, short, long double
DEMO: MATRIX MULTIPLICATION
用 C++ 的理由• 只會寫 C/C++ (?)• 移植 C/C++-based library
– Using SQLite in a Metro Style App
• 為了更好的效能– 針對平台的加速– 使用 AMP 利用 GPU 做平行運算– 操作 COM
• 更極致的效能調校• 使用 DirectX 11 開發遊戲
參考資源• Visual C++ Language Reference (C++/CX)
http://msdn.microsoft.com/en-us/library/windows/apps/hh699871.aspx
• Developing Windows 8 Metro style apps with C++http://channel9.msdn.com/Events/Windows-Camp/Developing-Windows-8-Metro-style-apps-in-Cpp
• Win32 and COM APIhttp://msdn.microsoft.com/en-us/library/windows/apps/br205757
• AMP MSDN Libraryhttp://msdn.microsoft.com/en-us/library/hh265137(v=vs.110)Native Concurrency Bloghttp://blogs.msdn.com/b/nativeconcurrency/
• Developing gameshttp://msdn.microsoft.com/en-us/library/windows/apps/hh452744.aspx
• Visual C++ Team Bloghttp://blogs.msdn.com/b/vcblog/
Recommended