Korzystanie z C++ AMP w aplikacjach platformy uniwersalnej systemu Windows
W aplikacji platforma uniwersalna systemu Windows (UWP) można użyć języka C++ AMP (C++ Accelerated Massive Parallelism) do wykonywania obliczeń na procesorze GPU (graphics Processing Unit) lub innych akceleratorów obliczeniowych. Jednak język C++ AMP nie zapewnia interfejsów API do bezpośredniej pracy z typami środowisko wykonawcze systemu Windows, a środowisko wykonawcze systemu Windows nie zapewnia otoki dla języka C++ AMP. W przypadku używania typów środowisko wykonawcze systemu Windows w kodzie — w tym utworzonych samodzielnie — należy przekonwertować je na typy zgodne z językiem C++ AMP.
Uwaga
Nagłówki C++ AMP są przestarzałe, począwszy od programu Visual Studio 2022 w wersji 17.0.
Dołączenie wszystkich nagłówków AMP spowoduje wygenerowanie błędów kompilacji. Zdefiniuj _SILENCE_AMP_DEPRECATION_WARNINGS
przed dołączeniem żadnych nagłówków AMP, aby wyciszyć ostrzeżenia.
Zagadnienia dotyczące wydajności
Jeśli używasz rozszerzeń składników języka Visual C++/CX do tworzenia aplikacji platforma uniwersalna systemu Windows (UWP), zalecamy używanie typów zwykłych starych danych (POD) wraz z ciągłym magazynem — na przykład std::vector
tablicami w stylu języka C — w przypadku danych, które będą używane z językiem C++ AMP. Może to pomóc w osiągnięciu wyższej wydajności niż przy użyciu typów innych niż POD lub kontenerów środowisko wykonawcze systemu Windows, ponieważ nie ma potrzeby marshalingu.
W jądrze C++ AMP, aby uzyskać dostęp do danych przechowywanych w ten sposób, po prostu opakuj std::vector
magazyn tablicy lub w obiekcie concurrency::array_view
, a następnie użyj 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];
});
Szeregowanie typów środowiska wykonawczego systemu Windows
Podczas pracy z interfejsami API środowisko wykonawcze systemu Windows możesz użyć języka C++ AMP na danych przechowywanych w kontenerze środowisko wykonawcze systemu Windows, takim jak lub w złożonych typach danych, takich jak Platform::Array<T>^
klasy lub struktury zadeklarowane za pomocą słowa kluczowego ref lub słowa kluczowego wartości. W takich sytuacjach należy wykonać dodatkową pracę, aby udostępnić dane C++ AMP.
Platform::Array<T>^, gdzie T jest typem zasobnika
Jeśli napotkasz typ zasobnika Platform::Array<T>^
i T, możesz uzyskać dostęp do jego bazowego magazynu tylko za pomocą funkcji składowej get
:
Platform::Array<float>^ arr; // Assume that this was returned by a Windows Runtime API
concurrency::array_view<float, 1> av(arr->Length, &arr->get(0));
Jeśli typ T nie jest typem zasobnika, użyj techniki opisanej w poniższej sekcji, aby użyć danych z językiem C++ AMP.
Typy środowiska wykonawczego systemu Windows: klasy odniesienia i klasy wartości
Język C++ AMP nie obsługuje złożonych typów danych. Obejmuje to typy inne niż POD i wszelkie typy zadeklarowane przy użyciu słowa kluczowego ref lub słowa kluczowego wartości . Jeśli w restrict(amp)
kontekście jest używany nieobsługiwany typ, generowany jest błąd czasu kompilacji.
W przypadku napotkania nieobsługiwanego typu można skopiować interesujące części jego danych do concurrency::array
obiektu. Oprócz udostępniania danych dla języka C++ AMP do użycia, to podejście ręcznego kopiowania może również poprawić wydajność poprzez maksymalizację lokalizacji danych i zapewnienie, że dane, które nie będą używane, nie zostaną skopiowane do akceleratora. Wydajność można dodatkowo poprawić przy użyciu tablicy przejściowej, która jest specjalną formą concurrency::array
, która stanowi wskazówkę dla środowiska uruchomieniowego AMP, że tablica powinna być zoptymalizowana pod kątem częstego transferu między nią a innymi tablicami w określonym akceleratorze.
// 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ż
Tworzenie pierwszej aplikacji platformy UWP przy użyciu języka C++
Tworzenie składników środowisko wykonawcze systemu Windows w języku C++
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla