Utilizzo degli oggetti accelerator e accelerator_view
È possibile utilizzare le classi accelerator e accelerator_view per specificare un dispositivo o un emulatore su cui eseguire il codice C++ AMP.Un sistema potrebbe avere diversi dispositivi o emulatori che differiscono per quantità di memoria, supporto di debug, o supporto alla doppia precisione.Il Parallelismo Massiccio Accelerato di C++ (AMP C++) fornisce le API utilizzabili per esaminare gli acceleratori disponibili, impostarne uno come predefinito, specificare più acceleratori per più chiamate a parallel_for_each ed eseguire attività di debug speciali.
Utilizzare gli Accelerator predefiniti
Il runtime di AMP C++ seleziona un acceleratore predefinito, ad eccezione di scrivere codice per selezionarne uno specifico.Il runtime sceglie l'accelerator predefinito come segue:
Se l'applicazione è in esecuzione in modalità di debug, un acceleratore che supporti il debug.
In caso contrario, l'acceleratore specificato dalla variabile di ambiente CPPAMP_DEFAULT_ACCELERATOR, se è impostata.
Altrimenti, un dispositivo non emulato.
In caso contrario, il dispositivo con la maggiore quantità di memoria disponibile.
Altrimenti, un dispositivo che non è incluso nella visualizzazione.
È possibile determinare le proprietà del acceleratore predefinito mediante la costruzione del acceleratore predefinito ed esaminando sue proprietà.Nell'esempio di codice riportato di seguito viene stampato il percorso, la memoria e il supporto alla precisione doppia del tasto dell'acceleratore predefinito.
void default_properties() {
accelerator default_acc;
std::wcout << default_acc.device_path << "\n";
std::wcout << default_acc.dedicated_memory << "\n";
std::wcout << (default_acc.supports_double_precision ?
"double precision: true" : "double precision: false") << "\n";
}
Variabile di ambiente CPPAMP_DEFAULT_ACCELERATOR
È possibile impostare la variabile di ambiente CPPAMP_DEFAULT_ACCELERATOR per specificare accelerator::device_path dell'acceleratore predefinito.Il percorso è dipendente dall'hardware.Il codice seguente utilizza la funzione accelerator::get_all per recuperare un elenco di acceleratori disponibili e quindi visualizzare il percorso di ogni acceleratore.
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_double_precision ?
"double precision: true" : "double precision: false") << "\n";
}
}
Selezione di un Acceleratore
Per selezionare un acceleratore, utilizzare il metodo accelerator::get_all per recuperare un elenco di acceleratori disponibili e quindi selezionarne uno in base alle relative proprietà.In questo esempio viene illustrato come selezionare l'acceleratore havente la maggior memoria:
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";
}
[!NOTA]
Uno degli acceleratori restituiti da accelerator::get_all è l'acceleratore della CPU.Non è possibile eseguire codice sull'acceleratore della CPU.Per filtrare l'acceleratore della CPU, confrontare il valore della proprietà device_path dell'acceleratore restituito da accelerator::get_all con il valore accelerator::cpu_accelerator.Per ulteriori informazioni, vedere la sezione "Acceleratori Speciali" in questo articolo.
Modificare gli Acceleratori Predefiniti
È possibile modificare l'acceleratore predefinito chiamando il metodo accelerator::set_default.È possibile modificare l'acceleratore predefinito solo una volta per esecuzione dell'applicazione ed è necessario modificarlo prima che il codice venga eseguito su GPU.Qualsiasi successiva chiamata di funzione per modificare l'acceleratore restituisce false.Se si desidera utilizzare un acceleratore diverso in una chiamata a parallel_for_each, vedere la sezione “Usare più acceleratori" in questo articolo.Nell'esempio di codice riportato viene impostato l'acceleratore predefinito ad uno che non è collegato ad un display e supporta la doppia precisione.
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;
}
Utilizzo di più acceleratori
Esistono due modi per utilizzare multipli acceleratori nell'applicazione:
È possibile passare oggetti accelerator_view a chiamate al metodo parallel_for_each.
È possibile creare un oggetto array utilizzando uno specifico oggetto accelerator.Il runtime di C++ AMP prenderà l'oggetto accelerator_view dall'oggetto array acquisito nella lambda espressione .
Acceleratori speciali
I percorsi di dispositivo di tre acceleratori speciali sono disponibili come proprietà della classe accelerator :
Membro dati accelerator::direct3d_ref: Questo acceleratore a thread singolo utilizza il software sulla CPU per emulare una scheda grafica generica.Utilizzato in maniera predefinita per il debug, ma non è utile in produzione perché è più lento degli acceleratori hardware.Inoltre, è disponibile solo in DirectX SDK e Windows SDK ed è improbabile che possa essere installato nei computer dei clienti.Per ulteriori informazioni, vedere Debug del codice GPU.
Membro dati accelerator::direct3d_warp: Questo acceleratore fornisce una soluzione di riserva per eseguire il codice di AMP C++ in CPU multicore che utilizzano le estensioni Streaming SIMD (SSE).
Membro dati accelerator::cpu_accelerator: È possibile utilizzare questo acceleratore per impostare le matrici di gestione temporanea.Non può eseguire il codice C++ AMP.Per ulteriori informazioni, vedere il post Matrici di gestione temporanea in AMP C++ post sulla Programmazione Parallela nel blog del Codice Nativo.
Interoperabilità
Il runtime di AMP C++ supporta l'interoperabilità tra la classe accelerator_view e l' interfaccia di ID3D11Device Direct3d .Il metodo create_accelerator_view accetta un'interfaccia IUnknown e restituisce un oggetto accelerator_view.Il metodo get_device accetta un oggetto accelerator_view e restituisce un'interfaccia IUknown.