Korzystanie z C++ AMP w aplikacjach sklepu Windows Store
C++ AMP (C++ przyspieszane ogromne równoległości) można użyć w swojej Windows Store aplikacji do wykonywania obliczeń na GPU (grafika procesor) albo innych akceleratory obliczeniowych.Jednak dla pracy bezpośrednio z typami obsługi Windows (WinRT) w C++ AMP nie są dostępne interfejsy API i WinRT nie przewidują otoka C++ AMP.Użycie typów WinRT w kodzie — łącznie z tymi, które utworzono samodzielnie — przekonwertuj je na typy, które są zgodne z C++ AMP.
Zagadnienia dotyczące wydajności
Jeśli używasz Rozszerzenia składników dla programu Visual C++ (C++/CX) do tworzenia sieci Windows Store aplikacji, firma Microsoft zaleca używanie typów plain old danych (POD) razem z magazynem sąsiadujących ze sobą — na przykład, std::vector lub tablic w stylu języka C — dla danych, który będzie używany z C++ AMP.Może to pomóc osiągnąć wyższą wydajność niż za pomocą typów non-POD lub kontenery RT systemu Windows, ponieważ nie kierowanie musi nastąpić.
W jądrze C++ AMP, dostępu do danych przechowywaną w ten sposób tylko Zawijaj std::vector lub array, składowanie w concurrency::array_view , a następnie użyć widoku tablicy w concurrency::parallel_for_each pętli:
// 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];
});
Kierowanie typy systemu Windows w czasie wykonywania
Podczas pracy z interfejsów API WinRT, możesz chcieć używać C++ AMP na dane przechowywane w kontenerze WinRT takich jak Platform::Array<T>^ lub złożone typy danych takich jak klasy lub strukturach, które są zadeklarowane za pomocą ref słowa kluczowego lub value słowa kluczowego.W takich sytuacjach trzeba wykonywania dodatkowej pracy, aby udostępnić te dane do Wzmacniacza C++.
Platform::Array <T> ^, gdzie T jest typ POD
Jeśli pojawił Platform::Array<T>^ i T jest typu POD, jego składowania podstawowych można uzyskać dostęp tylko za pomocą get funkcji składowej:
Platform::Array<float>^ arr; // Assume that this was returned by a WinRT API
concurrency::array_view<float, 1> av(arr->Length, &arr->get(0));
Jeśli T nie jest typem POD, użyć techniki, którą opisano w poniższej sekcji, aby użyć danych z języka C++ AMP.
Typy systemu Windows w czasie wykonywania: klasy ref i wartość klasy
C++ AMP nie obsługuje złożone typy danych.Obejmuje to typy nie POD i żadnych typów, które są zadeklarowane za pomocą ref słowa kluczowego lub value słowa kluczowego.Jeśli nieobsługiwany typ jest używany w restrict(amp) jest generowany kontekstu, błąd kompilacji.
W przypadku wystąpienia nieobsługiwanego typu, można skopiować interesujących części jego danych do concurrency::array obiektu.Oprócz tego, że dane dostępne dla języka C++ AMP do konsumpcji, takie podejście obsługi kopiowania może również zwiększyć wydajność przez maksymalne wykorzystanie danych miejscowości, a także poprzez zapewnienie, że dane, które nie będą używane, nie jest kopiowany do akceleratora.Można poprawić wydajność dalej za pomocą tymczasowej tablicy, który jest szczególna forma concurrency::array , który stanowi wskazówkę AMP runtime że tablicy powinny być zoptymalizowane pod kątem częste transferu między nim a innymi tablicami na podanego akceleratora.
// 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;
});
Zobacz też
Inne zasoby
Tworzenie pierwszej aplikacji magazynu systemu Windows przy użyciu języka C++
Tworzenie składników systemu Windows środowiska wykonawczego języka c++