Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Du kan använda C++ AMP (C++ Accelerated Massive Parallelism) i din UWP-app (Universal Windows Platform) för att utföra beräkningar på GPU (grafikprocessorn) eller andra beräkningsacceleratorer. C++ AMP tillhandahåller dock inte API:er för att arbeta direkt med Windows Runtime-typer och Windows Runtime tillhandahåller ingen omslutning för C++ AMP. När du använder Windows Runtime-typer i koden, inklusive de som du har skapat själv, måste du konvertera dem till typer som är kompatibla med C++ AMP.
Anmärkning
C++ AMP-huvuden är inaktuella från och med Visual Studio 2022 version 17.0.
Om du inkluderar AMP headers uppstår byggfel. Definiera _SILENCE_AMP_DEPRECATION_WARNINGS innan du inkluderar AMP-huvuden för att undvika varningarna.
Prestandaöverväganden
Om du använder Visual C++-komponenttillägg C++/CX för att skapa din UWP-app (Universal Windows Platform) rekommenderar vi att du använder POD-typer (plain-old-data) tillsammans med sammanhängande lagring – std::vector till exempel matriser i C-stil – för data som ska användas med C++ AMP. Detta kan hjälpa dig att uppnå högre prestanda än genom att använda icke-POD-typer eller Windows Runtime-containrar eftersom ingen marskalkering behöver utföras.
För att komma åt data som lagras på detta sätt i en C++ AMP-kernel, omslut bara std::vector eller datalagringen i en concurrency::array_view och använd sedan matrisvyn i en concurrency::parallel_for_each-loop.
// 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];
});
Samla Windows Runtime-typer
När du arbetar med Windows Runtime-API:er kanske du vill använda C++ AMP på data som lagras i en Windows Runtime-container, till exempel en Platform::Array<T>^ eller i komplexa datatyper, till exempel klasser eller structs som deklareras med hjälp av nyckelordet ref eller nyckelordet value . I dessa situationer måste du göra lite extra arbete för att göra data tillgängliga för C++ AMP.
Plattform::Matris<T>^, där T är en POD-typ
När du stöter på en Platform::Array<T>^ och T är en POD-typ kan du komma åt dess underliggande lagring endast genom att använda get-medlemsfunktionen:
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));
Om T inte är en POD-typ använder du den teknik som beskrivs i följande avsnitt för att använda data med C++ AMP.
Windows Runtime-typer: referensklasser och värdeklasser
C++ AMP stöder inte komplexa datatyper. Detta omfattar icke-POD-typer och alla typer som deklareras med hjälp av nyckelordet referens eller nyckelordet värde . Om en typ som inte stöds används i en restrict(amp) kontext genereras ett kompileringsfel.
När du stöter på en typ som inte stöds kan du kopiera intressanta delar av dess data till ett concurrency::array objekt. Förutom att göra data tillgängliga för C++ AMP att använda kan den här metoden för manuell kopiering också förbättra prestanda genom att maximera datalokaliteten och genom att se till att data som inte används inte kopieras till acceleratorn. Du kan förbättra prestanda ytterligare med hjälp av en mellanlagringsmatris, som är en särskild form av concurrency::array som ger ett tips till AMP-körningen om att matrisen ska optimeras för frekvent överföring mellan den och andra matriser på den angivna acceleratorn.
// 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;
});
Se även
Skapa din första UWP-app med C++
Skapa Windows Runtime-komponenter i C++