Obiekty accelerator i accelerator_view
Można użyć klas accelerator i accelerator_view do określenia urządzenia lub emulatora do uruchamiania kodu C++ AMP.System może mieć kilka urządzeń lub emulatorów różniących się ilością pamięci, obsługą debugowania lub wsparciem dla podwójnej precyzji.Biblioteka C++ Accelerated Massive Parallelism (C++ AMP) udostępnia interfejsy API, które można wykorzystać do analizy dostępnych akceleratorów, ustawienie jednego z nich jako domyślny, określenia wielu akceleratorów dla wielu wywołań parallel_for_each oraz wykonywania specjalnych zadań debugowania.
Używanie akceleratora domyślnego
Środowisko wykonawcze C++ AMP wybiera akcelerator domyślny, o ile nie zostanie napisany kod wybierający konkretny akcelerator.Środowisko wykonawcze wybiera akcelerator domyślny w następujący sposób:
Jeśli aplikacja jest uruchomiona w trybie debugowania, akcelerator obsługujący debugowanie.
W przeciwnym razie akcelerator, który jest określony przez zmienną środowiskową CPPAMP_DEFAULT_ACCELERATOR, jeśli jest ustawiona.
W przeciwnym razie urządzenie emulowane.
W przeciwnym razie urządzenie, które ma największą ilość dostępnej pamięci.
W przeciwnym razie urządzenie, które nie jest dołączone do wyświetlania.
Można określić właściwości domyślnego akceleratora poprzez skonstruowanie domyślnego akceleratora i zbadanie jego właściwości.Poniższy przykład kodu wypisuje ścieżkę, pamięci i obsługę podwójnej precyzji przez akcelerator domyślny.
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";
}
Zmienna środowiskowa CPPAMP_DEFAULT_ACCELERATOR
Można ustawić zmienną środowiskową CPPAMP_DEFAULT_ACCELERATOR, aby określić accelerator::device_path akceleratora domyślnego.Ścieżka jest zależna od sprzętu.Następujący kod używa funkcji accelerator::get_all, aby pobrać listę dostępnych akceleratorów, a następnie wyświetlić ścieżkę każdego akceleratora.
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";
}
}
Wybieranie akceleratora
Aby wybrać akcelerator, użyj metody accelerator::get_all do pobrania listy dostępnych akceleratorów, a następnie wybierz jeden na podstawie jego właściwości.Przykład pokazuje jak wybrać akcelerator, który ma najwięcej pamięci:
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";
}
[!UWAGA]
Jeden z akceleratorów, które są zwracane przez accelerator::get_all jest akcelerator procesora CPU.Nie można wykonywać kodu na akceleratorze procesora.Aby odfiltrować accelerator procesora CPU, porównaj wartość właściwości akceleratora device_path, który jest zwracany przez accelerator::get_all z wartością accelerator::cpu_accelerator.Aby uzyskać więcej informacji zobacz sekcję "Specjalne akceleratory" w niniejszym artykule.
Zmienianie akceleratora domyślnego
Akcelerator domyślny można zmienić, wywołując metodę accelerator::set_default.Akcelerator domyślny można zmienić tylko raz na wykonanie aplikacji i należy go zmienić przed wykonaniem jakiegokolwiek kodu na procesorze GPU.Wszystkie kolejne wywołania funkcji zmiany akceleratora zwracają wartośćfalse.Jeśli chcesz użyć innego akceleratora w wywołaniu parallel_for_each, przeczytaj sekcję "Używanie wielu akceleratorów" w niniejszym artykule.Poniższy przykład kodu ustawia akcelerator domyślny, który nie jest emulowany, nie jest podłączony do wyświetlania i obsługuje podwójną precyzję.
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;
}
Używanie wielu akceleratorów
Można użyć wielu akceleratorów w aplikacji na dwa sposoby:
Można przekazać obiekty accelerator_view do wywołań metody parallel_for_each.
Można skonstruować obiekt array za pomocą określonego obiektu accelerator.Środowisko wykonawcze C++ AMP wybierze obiekt accelerator_view z przechwyconych obiektów array w wyrażeniu lambda.
Akceleratory specjalne
Ścieżki urządzenia dla trzech akceleratorów specjalnych są dostępne jako właściwości klasy accelerator:
Accelerator::direct3d_ref Członkowskich danych: Ten akcelerator jednowątkowy używa oprogramowania CPU do emulowania rodzajowej karty graficznej.Jest używany domyślnie do debugowania, ale nie jest użyteczny podczas produkcji, ponieważ jest wolniejszy niż akceleratory sprzętowe.Ponadto jest dostępny tylko w zestawie DirectX SDK i SDK systemu Windows i jest mało prawdopodobne, aby był zainstalowany na komputerach klientów.Aby uzyskać więcej informacji, zobacz Debugowanie kodu GPU.
Accelerator::direct3d_warp Członkowskich danych: Akcelerator ten dostarcza rozwiązanie alternatywne do wykonywania kodu C++ AMP na wielordzeniowych procesorów, które używają rozszerzenia SSE (Streaming SIMD).
Accelerator::cpu_accelerator Członkowskich danych: Można to wykorzystać ten akcelerator do tworzenia tablic tymczasowych.Nie może wykonywać kodu C++ AMP.Aby uzyskać więcej informacji, zobacz post Tablice tymczasowe w C++ AMP na blogu Programowanie równoległe w kodzie natywnym.
Współdziałanie
Środowisko wykonawcze C++ AMP obsługuje współdziałanie między klasą accelerator_view i interfejsem Direct3D ID3D11Device.Metoda create_accelerator_view pobiera interfejs IUnknown i zwraca obiekt accelerator_view.Metoda get_device pobiera obiekt accelerator_view i zwraca interfejs IUknown.