Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A C++ AMP (C++ gyorsított masszív párhuzamosság) használatával az Univerzális Windows Platform (UWP) alkalmazásban számításokat végezhet a GPU-n (grafikus feldolgozási egységen) vagy más számítási gyorsítókon. A C++ AMP azonban nem biztosít API-kat a Közvetlen Windows-futtatókörnyezet-típusok kezeléséhez, és a Windows futtatókörnyezet nem biztosít burkolót a C++ AMP-hez. Ha windowsos futtatókörnyezet-típusokat használ a kódban – beleértve azokat is, amelyeket ön hozott létre –, a C++ AMP-vel kompatibilis típusokká kell konvertálnia őket.
Megjegyzés:
A C++ AMP fejlécek elavultak a Visual Studio 2022 17.0-s verziójától kezdve.
Az AMP-fejlécek beépítése építési hibákat fog okozni. A figyelmeztetések elnémításához a _SILENCE_AMP_DEPRECATION_WARNINGS definiálása előtt az AMP-fejléceket be kell vonni.
Teljesítménnyel kapcsolatos szempontok
Ha a C++/CX Visual C++-összetevőbővítményeket használja az univerzális Windows Platform (UWP) alkalmazás létrehozásához, javasoljuk, hogy a C++ AMP-vel használni kívánt adatokhoz használjon egyszerű eredeti adattípusokat (POD) az egybefüggő tárterületekkel (például std::vector vagy C-stílusú tömbökkel). Ez segíthet abban, hogy nagyobb teljesítményt érjen el, mint a nem POD típusok vagy a Windows Runtime tárolók használatával, mivel nincs szükség marsallálásra.
Egy C++ AMP-kernelben az így tárolt adatok eléréséhez egyszerűen csomagolja be a std::vector-t vagy a tömbtárolót egy concurrency::array_view-be, majd használja az array view-t egy concurrency::parallel_for_each hurokban:
// 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 Runtime típusok kezelése
A Windows Runtime API-k használatakor érdemes lehet a C++ AMP-t használni a Windows Futtatókörnyezet tárolóban tárolt adatokon, például egy Platform::Array<T>^ vagy összetett adattípusokban, például osztályokban vagy szerkezetekben, amelyeket a ref kulcsszóval vagy az érték kulcsszóval deklaráltak. Ezekben az esetekben további munkát kell végeznie, hogy az adatokat elérhetővé tegye a C++ AMP számára.
Platform::tömb<T>^, ahol T egy POD típus
Ha megjelenik egy Platform::Array<T>^ és a T egy POD típus, az alapjául szolgáló tárhelyet elérheti a get tagfüggvény használatával:
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));
Ha a T nem POD típusú, használja a következő szakaszban ismertetett technikát az adatok C++ AMP-vel való használatához.
Windows futtatókörnyezet-típusok: ref osztályok és értékosztályok
A C++ AMP nem támogatja az összetett adattípusokat. Ide tartoznak a nem POD-típusok és a ref kulcsszóval vagy az érték kulcsszóval deklarált típusok. Ha egy restrict(amp) környezetben nem támogatott típust használ, fordítási idejű hiba keletkezik.
Ha nem támogatott típussal találkozik, az adatok érdekes részeit átmásolhatja egy concurrency::array objektumba. Amellett, hogy a C++ AMP számára elérhetővé teszi az adatokat, ez a manuális másolási módszer az adat helyének maximalizálásával és annak biztosításával is javíthatja a teljesítményt, hogy a nem használt adatok ne legyenek átmásolva a gázpedálba. A teljesítményt tovább javíthatja egy átmeneti tömb használatával, amely az AMP futtatókörnyezetének speciális formája, és utal arra, hogy a tömböt optimalizálni kell a megadott gyorsító eszköz és más tömbök közötti gyakori átvitelhez.
// 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;
});
Lásd még
Az első UWP-alkalmazás létrehozása a C++ használatával
Windows futtatókörnyezeti összetevők létrehozása a C++ rendszerben