Windows ストア アプリでの C++ AMP の使用
独自のアプリケーションで Windows ストア GPU (単位を処理するグラフィックス) または他の計算のアクセラレータ計算の実行に C++ AMP (C++ で加速された大きい並列) を使用できます。ただし、C++ AMP ランタイムは Windows の (WinRT) の型を直接使用するための API に属し、WinRT は C++ AMP.のラッパーを提供しません。使用するとき WinRT は C++ AMP.と互換性のある型に、を独自に変換する必要がある作成したコードが、それらの型が表示されます。
パフォーマンスに関する考慮事項
自分の Windows ストア アプリケーションの作成に Visual C++ コンポーネント拡張 (C++/CX) を使用すると、は C++ AMP.で使用するデータ配列の例 std::vector、または C スタイル ストレージの実行とともに立ちません古データの (POD) の型を使用することをお勧めします。これは、マーシャリングの必要がないため、非 POD 型または RT Windows のコンテナーを使用して、より高いパフォーマンスを実現するうえで役立ちます。
C ++. AMP のカーネルでは、この方法で格納されているデータにアクセスするには、std::vector をラップするか、concurrency::array_view の配列を格納し、concurrency::parallel_for_each のループでは、配列のビューの使用:
// simple vector addition example
std::vector<int> data0(1024, 1);
std::vector<int> data1(1024, 2);
std::vector<int> data_out(data0.size(), 0);
concurrency::array_view<int, 1> av0(data0.size(), data0);
concurrency::array_view<int, 1> av1(data1.size(), data1);
concurrency::array_view<int, 1> av2(data_out.size(), data2);
av2.discard_data();
concurrency::parallel_for_each(av0.extent, [=](concurrency::index<1> idx) restrict(amp)
{
av2[idx] = av0[idx] + av1[idx];
});
マーシャリングの Windows のランタイム型
WinRT API を使用すると、Platform::Array<T>^ などの WinRT コンテナーまたは ref の value のキーワードまたはキーワードを使用して宣言された構造体またはクラスなどの複合データ型に格納されているデータの AMP C++ を使用する場合があります。この場合、C++ AMP.でデータを使用できるように特別な作業を行う必要があります。
T が POD 型)、Platform::Array<T>の ^
Platform::Array<T>^ を検出し、T が POD 型である場合 get のメンバー関数を使用して基になるストレージにだけアクセスできます:
Platform::Array<float>^ arr; // Assume that this was returned by a WinRT API
concurrency::array_view<float, 1> av(arr->Length, &arr->get(0));
T が POD 型でない場合、C++ AMP.でデータを使用するには、次のセクションで説明する技術を使用します。
Windows のランタイム型: ref クラスおよび値クラス
C++ AMP は、複雑なデータ型をサポートしません。これは ref の value のキーワードまたはキーワードを使用して宣言される非 POD 型と型が含まれています。サポートされていない型が restrict(amp) のコンテキストで使用されている場合、コンパイル時エラーが生成されます。
サポートされない型を検出すると、concurrency::array のオブジェクトにデータの重要な部分をコピーできます。C++ AMP のデータの作成に加えてこの手動コピーの方法では、データの局所性を最大にすることで、実行すると、パフォーマンスが向上するため、使用されていないデータはアクセラレータにコピーします。配列は、必要であると他の配列間の頻繁なコピー用に最適化された提供すること AMP のランタイムに指定されたアクセラレータでツールヒントを concurrency::array の特殊な形式である ステージング配列を使用してパフォーマンスをさらに向上します。
// pixel_color.h
ref class pixel_color sealed
{
public:
pixel_color(Platform::String^ color_name, int red, int green, int blue)
{
name = color_name;
r = red;
g = green;
b = blue;
}
property Platform::String^ name;
property int r;
property int g;
..property int b;
};
// Some other file
std::vector<pixel_color^> pixels (256);
for(pixel_color ^pixel : pixels)
{
pixels.push_back(ref new pixel_color("blue", 0, 0, 255));
}
// Create the accelerators
auto cpuAccelerator = concurrency::accelerator(concurrency::accelerator::cpu_accelerator);
auto devAccelerator = concurrency::accelerator(concurrency::accelerator::default_accelerator);
// Create the staging arrays
concurrency::array<float, 1> red_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);
concurrency::array<float, 1> blue_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);
// Extract data from the complex array of structs into staging arrays.
concurrency::parallel_for(0, 256, [&](int i)
{
red_vec[i] = pixels[i]->r;
blue_vec[i] = pixels[i]->b;
});
// Array views are still used to copy data to the accelerator
concurrency::array_view<float, 1> av_red(red_vec);
concurrency::array_view<float, 1> av_blue(blue_vec);
// Change all pixels from blue to red.
concurrency::parallel_for_each(av_red.extent, [=](index<1> idx) restrict(amp)
{
av_red[idx] = 255;
av_blue[idx] = 0;
});