Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
U kunt de accelerator en accelerator_view klassen gebruiken om het apparaat of de emulator op te geven waarop uw C++ AMP-code moet worden uitgevoerd. Een systeem kan verschillende apparaten of emulators hebben die verschillen per hoeveelheid geheugen, ondersteuning voor gedeeld geheugen, ondersteuning voor foutopsporing of ondersteuning voor dubbele precisie. C++ Accelerated Massive Parallelism (C++ AMP) biedt API's die u kunt gebruiken om de beschikbare accelerators te onderzoeken, er een in te stellen als de standaardinstelling, meerdere accelerator_views op te geven voor meerdere aanroepen naar parallel_for_each en speciale foutopsporingstaken uit te voeren.
Opmerking
C++ AMP-headers worden afgeschaft vanaf Visual Studio 2022 versie 17.0.
Als u AMP-headers opneemt, zullen er buildfouten optreden. Definieer _SILENCE_AMP_DEPRECATION_WARNINGS voordat u AMP-headers opneemt om de waarschuwingen te onderdrukken.
De standaardversneller gebruiken
De C++ AMP-runtime kiest een standaardversneller, tenzij u code schrijft om een specifieke te kiezen. De runtime kiest de standaardversneller als volgt:
Als de app wordt uitgevoerd in de foutopsporingsmodus, een accelerator die ondersteuning biedt voor foutopsporing.
Anders, als deze is ingesteld, is de accelerator die door de omgevingsvariabele
CPPAMP_DEFAULT_ACCELERATORis opgegeven.Anders betreft het een niet-geëmuleerd apparaat.
Anders is het het apparaat dat de grootste hoeveelheid beschikbaar geheugen heeft.
Anders is er een apparaat dat niet gekoppeld is aan het beeldscherm.
Daarnaast specificeert de runtime-omgeving een access_type van access_type_auto voor de standaardversneller. Dit betekent dat de standaard accelerator gebruikmaakt van gedeeld geheugen als dit wordt ondersteund en als de prestatiekenmerken (bandbreedte en latentie) bekend zijn en gelijk zijn aan toegewezen (niet-gedeeld) geheugen.
U kunt de eigenschappen van de standaardversneller bepalen door de standaardversneller samen te stellen en de eigenschappen ervan te controleren. In het volgende codevoorbeeld worden het pad, de hoeveelheid geheugen van de accelerator, ondersteuning voor gedeeld geheugen, ondersteuning voor dubbele precisie en beperkte ondersteuning voor dubbele precisie van de standaardversneller afgedrukt.
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";
}
Omgevingsvariabele CPPAMP_DEFAULT_ACCELERATOR
U kunt de CPPAMP_DEFAULT_ACCELERATOR omgevingsvariabele instellen om de accelerator::device_path standaardversneller op te geven. Het pad is hardwareafhankelijk. De volgende code gebruikt de accelerator::get_all functie om een lijst met beschikbare accelerators op te halen en geeft vervolgens het pad en de kenmerken van elke accelerator weer.
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";
}
}
Een accelerator selecteren
Als u een accelerator wilt selecteren, gebruikt u de accelerator::get_all methode om een lijst met de beschikbare accelerators op te halen en selecteert u er vervolgens een op basis van de eigenschappen. In dit voorbeeld ziet u hoe u de accelerator kiest die het meeste geheugen heeft:
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";
}
Opmerking
Een van de accelerators die worden geretourneerd door accelerator::get_all is de CPU-accelerator. U kunt geen code uitvoeren op de CPU-accelerator. Als u de CPU-accelerator wilt filteren, vergelijkt u de waarde van de eigenschap device_path van de accelerator die wordt geretourneerd door accelerator::get_all met de waarde van de accelerator::cpu_accelerator. Zie de sectie Speciale accelerators in dit artikel voor meer informatie.
Gedeeld geheugen
Gedeeld geheugen is geheugen dat toegankelijk is voor zowel de CPU als de accelerator. Het gebruik van gedeeld geheugen elimineert of vermindert de overhead van het kopiëren van gegevens tussen de CPU en de accelerator aanzienlijk. Hoewel het geheugen wordt gedeeld, kan het niet gelijktijdig worden geopend door zowel de CPU als de accelerator, en zorgt dit voor niet-gedefinieerd gedrag. De eigenschap accelerator supports_cpu_shared_memory retourneert true als de accelerator ondersteuning biedt voor gedeeld geheugen en de eigenschap default_cpu_access_type het standaardtoegangstype ophaalt voor geheugen dat bijvoorbeeld is toegewezen aan acceleratormatrices die zijn gekoppeld aan de accelerator of array_view objecten die op de accelerator accelerator zijn geopend.
De C++ AMP-runtime kiest automatisch de beste standaardinstelling access_type voor elk accelerator, maar de prestatiekenmerken (bandbreedte en latentie) van gedeeld geheugen kunnen slechter zijn dan die van toegewezen (niet-gedeeld) acceleratorgeheugen bij het lezen van de CPU, schrijven vanuit de CPU of beide. Als gedeeld geheugen net zo goed presteert als toegewezen geheugen voor lezen en schrijven van de CPU, zal de runtime standaard access_type_read_write gebruiken; anders kiest de runtime een conservatievere standaard optie access_type en kan de app deze aanpassen als de geheugentoegangspatronen van de computatiekernels profiteren van een andere access_type.
In het volgende codevoorbeeld ziet u hoe u kunt bepalen of de standaardversneller gedeeld geheugen ondersteunt en vervolgens het standaardtoegangstype overschrijft en er een accelerator_view van maakt.
#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;
}
Een accelerator_view weerspiegelt altijd de default_cpu_access_type van de accelerator waaraan het is gekoppeld, en biedt geen interface om de access_type te overschrijven of te wijzigen.
De standaardversneller wijzigen
U kunt de standaardversneller wijzigen door de accelerator::set_default methode aan te roepen. U kunt de standaardversneller slechts eenmaal per app-uitvoering wijzigen en u moet deze wijzigen voordat code wordt uitgevoerd op de GPU. Eventuele volgende functie-aanroepen om de accelerator te wijzigen, zullen false retourneren. Als u een andere accelerator in een aanroep parallel_for_eachwilt gebruiken, leest u de sectie 'Meerdere accelerators gebruiken' in dit artikel. In het volgende codevoorbeeld wordt de standaardversneller ingesteld op een accelerator die niet is geëmuleerd, niet is verbonden met een beeldscherm en ondersteuning biedt voor dubbele precisie.
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;
}
Meerdere accelerators gebruiken
Er zijn twee manieren om meerdere accelerators in uw app te gebruiken:
U kunt
accelerator_viewobjecten doorgeven aan aanroepen van de methode parallel_for_each.U kunt een matrixobject maken met behulp van een specifiek
accelerator_viewobject. De C++ AMP-runtime haalt hetaccelerator_viewobject op uit het vastgelegde matrixobject in de lambda-expressie.
Speciale versnellers
De apparaatpaden van drie speciale accelerators zijn beschikbaar als eigenschappen van de accelerator klasse:
accelerator::direct3d_ref Data Member: Deze single-threaded accelerator maakt gebruik van software op de CPU om een gangbare grafische kaart te emuleren. Deze wordt standaard gebruikt voor foutopsporing, maar is niet nuttig in productie omdat deze langzamer is dan de hardwareversnellers. Bovendien is deze alleen beschikbaar in de DirectX SDK en de Windows SDK, en is het onwaarschijnlijk dat deze op de computers van uw klanten wordt geïnstalleerd. Zie GPU-code voor foutopsporingvoor meer informatie.
accelerator::direct3d_warp Data Member: Deze accelerator biedt een terugvaloplossing voor het uitvoeren van C++ AMP-code op multi-core CPU's die gebruikmaken van Streaming SIMD Extensions (SSE).
accelerator::cpu_accelerator Gegevenslid: u kunt deze accelerator gebruiken voor het instellen van faseringsmatrices. C++ AMP-code kan niet worden uitgevoerd. Zie de faseringsmatrices in C++ AMP-post op de blog Parallel Programming in Native Code voor meer informatie.
Interoperabiliteit
De C++ AMP-runtime ondersteunt interoperabiliteit tussen de accelerator_view klasse en de Direct3D ID3D11Device-interface. De methode create_accelerator_view gebruikt een IUnknown interface en retourneert een accelerator_view object. De methode get_device gebruikt een accelerator_view object en retourneert een IUnknown interface.
Zie ook
C++ AMP (C++ Versneld massaal parallellisme)
Debuggen van GPU-code
accelerator_view-klasse