Používání akcelerátoru a objektů accelerator_view
Akcelerátor a třídy accelerator_view můžete použít k určení zařízení nebo emulátoru pro spuštění kódu C++ AMP. Systém může mít několik zařízení nebo emulátorů, které se liší množstvím paměti, podporou sdílené paměti, podporou ladění nebo podporou dvojité přesnosti. C++ Akcelerovaný massive parallelism (C++ AMP) poskytuje rozhraní API, která můžete použít k prozkoumání dostupných akcelerátorů, nastavení jednoho jako výchozího, určení více accelerator_views pro více volání do parallel_for_each a provádění speciálních úloh ladění.
Poznámka:
Hlavičky C++ AMP jsou zastaralé od sady Visual Studio 2022 verze 17.0.
Zahrnutím všech hlaviček AMP se vygenerují chyby sestavení. Před zahrnutím záhlaví AMP definujte _SILENCE_AMP_DEPRECATION_WARNINGS
upozornění.
Použití výchozího akcelerátoru
Modul runtime C++ AMP vybere výchozí akcelerátor, pokud nezapíšete kód, který vybere konkrétní akcelerátor. Modul runtime zvolí výchozí akcelerátor následujícím způsobem:
Pokud je aplikace spuštěná v režimu ladění, akcelerátor, který podporuje ladění.
Jinak akcelerátor určený proměnnou
CPPAMP_DEFAULT_ACCELERATOR
prostředí, pokud je nastavený.V opačném případě neemulované zařízení.
V opačném případě zařízení, které má největší množství dostupné paměti.
V opačném případě zařízení, které není připojené k displeji.
Modul runtime navíc určuje access_type
výchozí access_type_auto
akcelerátor. To znamená, že výchozí akcelerátor používá sdílenou paměť, pokud je podporovaná a jestli jsou její charakteristiky výkonu (šířka pásma a latence) známé jako vyhrazená (nesdílená) paměť.
Vlastnosti výchozího akcelerátoru můžete určit tak, že vytvoříte výchozí akcelerátor a prozkoumáte jeho vlastnosti. Následující příklad kódu vytiskne cestu, velikost paměti akcelerátoru, podporu sdílené paměti, podporu dvojité přesnosti a omezenou podporu dvojité přesnosti výchozího akcelerátoru.
void default_properties() {
accelerator default_acc;
std::wcout << default_acc.device_path << "\n";
std::wcout << default_acc.dedicated_memory << "\n";
std::wcout << (accs[i].supports_cpu_shared_memory ?
"CPU shared memory: true" : "CPU shared memory: false") << "\n";
std::wcout << (accs[i].supports_double_precision ?
"double precision: true" : "double precision: false") << "\n";
std::wcout << (accs[i].supports_limited_double_precision ?
"limited double precision: true" : "limited double precision: false") << "\n";
}
proměnná prostředí CPPAMP_DEFAULT_ACCELERATOR
Proměnnou prostředí CPPAMP_DEFAULT_ACCELERATOR můžete nastavit tak, aby určila accelerator::device_path
výchozí akcelerátor. Cesta je závislá na hardwaru. Následující kód pomocí accelerator::get_all
funkce načte seznam dostupných akcelerátorů a pak zobrazí cestu a vlastnosti každého akcelerátoru.
void list_all_accelerators()
{
std::vector<accelerator> accs = accelerator::get_all();
for (int i = 0; i <accs.size(); i++) {
std::wcout << accs[i].device_path << "\n";
std::wcout << accs[i].dedicated_memory << "\n";
std::wcout << (accs[i].supports_cpu_shared_memory ?
"CPU shared memory: true" : "CPU shared memory: false") << "\n";
std::wcout << (accs[i].supports_double_precision ?
"double precision: true" : "double precision: false") << "\n";
std::wcout << (accs[i].supports_limited_double_precision ?
"limited double precision: true" : "limited double precision: false") << "\n";
}
}
Výběr akcelerátoru
Chcete-li vybrat akcelerátor, použijte metodu accelerator::get_all
k načtení seznamu dostupných akcelerátorů a pak vyberte jeden na základě jeho vlastností. Tento příklad ukazuje, jak vybrat akcelerátor, který má nejvíce paměti:
void pick_with_most_memory()
{
std::vector<accelerator> accs = accelerator::get_all();
accelerator acc_chosen = accs[0];
for (int i = 0; i <accs.size(); i++) {
if (accs[i].dedicated_memory> acc_chosen.dedicated_memory) {
acc_chosen = accs[i];
}
}
std::wcout << "The accelerator with the most memory is "
<< acc_chosen.device_path << "\n"
<< acc_chosen.dedicated_memory << ".\n";
}
Poznámka:
Jedním z akcelerátorů vrácených accelerator::get_all
je akcelerátor procesoru. V akcelerátoru procesoru nelze spustit kód. Chcete-li vyfiltrovat akcelerátor procesoru, porovnejte hodnotu vlastnosti device_path akcelerátoru vrácenou accelerator::get_all
hodnotou akcelerátoru::cpu_accelerator. Další informace najdete v části Speciální akcelerátory v tomto článku.
Sdílená paměť
Sdílená paměť je paměť, ke které má přístup procesor i akcelerátor. Použití sdílené paměti eliminuje nebo výrazně snižuje režii při kopírování dat mezi procesorem a akcelerátorem. I když je paměť sdílená, nelze k ní přistupovat současně procesorem i akcelerátorem a tím způsobit nedefinované chování. Vlastnost akcelerátoru supports_cpu_shared_memory vrátí true
, pokud akcelerátor podporuje sdílenou paměť, a vlastnost default_cpu_access_type získá výchozí access_type pro paměť přidělenou accelerator
paměti – například polepřidružená k objektu accelerator
nebo array_view
objekty, ke kterým se accelerator
přistupuje .
Modul runtime C++ AMP automaticky zvolí nejlepší výchozí hodnotu access_type
pro každou z nich accelerator
, ale charakteristiky výkonu (šířka pásma a latence) sdílené paměti můžou být horší než ty, které mají vyhrazenou (nesdílenou) paměť při čtení z procesoru, zápisu z procesoru nebo obojího. Pokud sdílená paměť provádí stejně jako vyhrazenou paměť pro čtení a zápis z procesoru, modul runtime výchozí access_type_read_write
hodnotu ; jinak modul runtime zvolí konzervativnější výchozí hodnotu access_type
a umožní aplikaci přepsat, pokud vzory přístupu k paměti jeho výpočetních jader mají prospěch z jiného access_type
.
Následující příklad kódu ukazuje, jak určit, zda výchozí akcelerátor podporuje sdílenou paměť, a pak přepíše jeho výchozí typ přístupu a vytvoří z něj.accelerator_view
#include <amp.h>
#include <iostream>
using namespace Concurrency;
int main()
{
accelerator acc = accelerator(accelerator::default_accelerator);
// Early out if the default accelerator doesn't support shared memory.
if (!acc.supports_cpu_shared_memory)
{
std::cout << "The default accelerator does not support shared memory" << std::endl;
return 1;
}
// Override the default CPU access type.
acc.set_default_cpu_access_type(access_type_read_write);
// Create an accelerator_view from the default accelerator. The
// accelerator_view reflects the default_cpu_access_type of the
// accelerator it's associated with.
accelerator_view acc_v = acc.default_view;
}
Vždy accelerator_view
odráží, k default_cpu_access_type
accelerator
čemu je přidružena, a neposkytuje žádné rozhraní k přepsání nebo změně jeho access_type
.
Změna výchozího akcelerátoru
Výchozí akcelerátor můžete změnit voláním accelerator::set_default
metody. Výchozí akcelerátor můžete změnit jenom jednou na spuštění aplikace a před spuštěním jakéhokoli kódu na GPU ho musíte změnit. Všechna následná volání funkce ke změně návratu false
akcelerátoru . Pokud chcete ve volání parallel_for_each
použít jiný akcelerátor, přečtěte si část Používání více akcelerátorů v tomto článku. Následující příklad kódu nastaví výchozí akcelerátor na ten, který není emulován, není připojen k displeji a podporuje dvojitou přesnost.
bool pick_accelerator()
{
std::vector<accelerator> accs = accelerator::get_all();
accelerator chosen_one;
auto result = std::find_if(accs.begin(), accs.end(),
[] (const accelerator& acc) {
return !acc.is_emulated &&
acc.supports_double_precision &&
!acc.has_display;
});
if (result != accs.end()) {
chosen_one = *(result);
}
std::wcout <<chosen_one.description <<std::endl;
bool success = accelerator::set_default(chosen_one.device_path);
return success;
}
Použití více akcelerátorů
V aplikaci můžete použít několik akcelerátorů dvěma způsoby:
Do volání metody parallel_for_each můžete předat
accelerator_view
objekty.Objekt pole můžete vytvořit pomocí konkrétního
accelerator_view
objektu. Modul runtime C+AMP vyzvedneaccelerator_view
objekt z zachyceného objektu pole ve výrazu lambda.
Speciální akcelerátory
Cesty zařízení tří speciálních akcelerátorů jsou k dispozici jako vlastnosti accelerator
třídy:
accelerator::d irect3d_ref Data Member: Tento akcelerátor s jedním vláknem používá software na procesoru k emulaci obecné grafické karty. Ve výchozím nastavení se používá k ladění, ale není užitečná v produkčním prostředí, protože je pomalejší než hardwarové akcelerátory. Kromě toho je k dispozici pouze v sadě DirectX SDK a sadě Windows SDK a je nepravděpodobné, že by se nainstalovala na počítače vašich zákazníků. Další informace najdete v tématu Ladění kódu GPU.
accelerator::d irect3d_warp – Datový člen: Tento akcelerátor poskytuje náhradní řešení pro spouštění kódu C++ AMP na vícejádrových procesorech, které používají rozšíření SSE (Streaming SIMD Extensions).
accelerator::cpu_accelerator Datový člen: Tento akcelerátor můžete použít k nastavení pracovních polí. Nelze spustit kód C++ AMP. Další informace najdete v příspěvku O přípravných polích v C++ AMP v blogovém příspěvku Paralelní programování v nativním kódu.
Vzájemná funkční spolupráce
Modul runtime C++ AMP podporuje interoperabilitu accelerator_view
mezi třídou a rozhraním Direct3D ID3D11Device. Create_accelerator_view metoda přebírá IUnknown
rozhraní a vrací accelerator_view
objekt. Metoda get_device přebírá accelerator_view
objekt a vrací IUnknown
rozhraní.
Viz také
C++ AMP (C++ Accelerated Massive Parallelism)
Ladění kódu GPU
accelerator_view – třída