使用 accelerator 和 accelerator_view 物件
您可以使用 快速鍵 和 accelerator_view 類別來指定要執行 C++ AMP 程式碼的裝置或模擬器。 系統可能會有數個裝置或模擬器,這些裝置與記憶體數量、共用記憶體支援、偵錯支援或雙精確度支援不同。 C++ 加速大規模平行處理原則 (C++ AMP) 提供 API,可讓您用來檢查可用的加速器、將一個設定為預設值、針對多個呼叫指定多個accelerator_views來parallel_for_each,以及執行特殊的偵錯工作。
注意
從 Visual Studio 2022 17.0 版開始,C++ AMP 標頭已被取代。
包含任何 AMP 標頭將會產生建置錯誤。 先定義 _SILENCE_AMP_DEPRECATION_WARNINGS
,再包含任何 AMP 標頭以讓警告無聲。
使用預設加速器
除非您撰寫程式碼來挑選特定加速器,否則 C++ AMP 執行時間會挑選預設加速器。 執行時間會選擇預設加速器,如下所示:
如果應用程式以偵錯模式執行,則為支援偵錯的加速器。
否則,
CPPAMP_DEFAULT_ACCELERATOR
如果已設定環境變數,則為加速器。否則為非模擬裝置。
否則,具有最大可用記憶體數量的裝置。
否則,未連結至顯示器的裝置。
此外,執行時間會 access_type
針對預設加速器指定 的 access_type_auto
。 這表示,如果支援預設加速器,以及其效能特性(頻寬和延遲)已知與專用(非共用)記憶體相同,則預設加速器會使用共用記憶體。
您可以藉由建構預設加速器並檢查其屬性,來判斷預設加速器的屬性。 下列程式碼範例會列印路徑、加速器記憶體數量、共用記憶體支援、雙精確度支援,以及預設加速器的有限雙精確度支援。
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";
}
CPPAMP_DEFAULT_ACCELERATOR環境變數
您可以設定CPPAMP_DEFAULT_ACCELERATOR環境變數來指定 accelerator::device_path
預設加速器的 。 路徑是硬體相依的。 下列程式碼會使用 函 accelerator::get_all
式來擷取可用加速器的清單,然後顯示每個加速器的路徑和特性。
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";
}
}
選取加速器
若要選取加速器,請使用 accelerator::get_all
方法來擷取可用加速器的清單,然後根據其屬性選取一個加速器。 此範例示範如何挑選具有最多記憶體的加速器:
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";
}
注意
所傳 accelerator::get_all
回的其中一個加速器是 CPU 加速器。 您無法在 CPU 加速器上執行程式碼。 若要篩選掉 CPU 加速器,請將 所傳回 accelerator::get_all
之快速鍵的 device_path 屬性值與 accelerator::cpu_accelerator 的值 進行比較 。 如需詳細資訊,請參閱本文中的一節。
共用記憶體
共用記憶體是 CPU 和加速器可以存取的記憶體。 使用共用記憶體可消除或大幅減少在 CPU 與加速器之間複製資料的額外負荷。 雖然記憶體已共用,但 CPU 和加速器無法同時存取記憶體,因此會導致未定義的行為。 如果快速鍵支援共用記憶體,且 default_cpu_access_type 屬性會針對 上配置的記憶體取得預設 access_type ,例如, 與 accelerator
上 accelerator
存取 accelerator
的 或 array_view
物件相關聯的陣列 ,則會傳回 true
快速鍵 supports_cpu_shared_memory 屬性 。
C++ AMP 執行時間會自動為每個 選擇最佳預設值 access_type
accelerator
,但共用記憶體的效能特性(頻寬和延遲)可能會比從 CPU 讀取、從 CPU 寫入或兩者讀取時專用(非共用)加速器記憶體的效能特性(頻寬和延遲)更差。 如果共用記憶體執行以及專用記憶體來讀取和寫入 CPU,則執行時間會預設為 access_type_read_write
;否則,執行時間會選擇更保守的預設 access_type
,而且如果計算核心的記憶體存取模式受益于不同的 access_type
,則允許應用程式覆寫它。
下列程式碼範例示範如何判斷預設加速器是否支援共用記憶體,然後覆寫其預設存取類型,並從中建立 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;
}
一 accelerator_view
律會 default_cpu_access_type
accelerator
反映其相關聯的 ,而且不會提供任何介面來覆寫或變更其 access_type
。
變更預設加速器
您可以呼叫 accelerator::set_default
方法來變更預設加速器。 您只能在每個應用程式執行時變更預設加速器一次,而且您必須在 GPU 上執行任何程式碼之前加以變更。 任何後續的函式呼叫,以變更加速器傳回 false
。 如果您想要在呼叫 parallel_for_each
中使用不同的加速器,請閱讀本文中的一節。 下列程式碼範例會將預設快速鍵設定為未模擬、未連線到顯示器,並支援雙精確度。
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;
}
使用多個加速器
在您的應用程式中使用多個加速器的方法有兩種:
您可以將 物件傳遞
accelerator_view
至 呼叫 parallel_for_each 方法。您可以使用特定
accelerator_view
物件來建構 陣列 物件。 C+AMP 執行時間會從 Lambda 運算式中擷取的 陣列 物件中挑選accelerator_view
物件。
特殊加速器
三個特殊加速器的裝置路徑可作為 類別的屬性 accelerator
:
accelerator::d irect3d_ref 資料成員 :此單一執行緒加速器會使用 CPU 上的軟體來模擬一般圖形卡。 它預設會用於偵錯,但它在生產環境中並不有用,因為它比硬體加速器慢。 此外,它只能在 DirectX SDK 和 Windows SDK 中使用,而且不太可能安裝在客戶的電腦上。 如需詳細資訊,請參閱 偵錯 GPU 程式碼 。
accelerator::d irect3d_warp 資料成員 :此加速器提供後援解決方案,可在使用串流 SIMD 延伸模組 (SSE) 的多核心 CPU 上執行 C++ AMP 程式碼。
accelerator::cpu_accelerator Data Member :您可以使用此加速器來設定預備陣列。 它無法執行 C++ AMP 程式碼。 如需詳細資訊,請參閱 《原生程式碼中的平行程式設計》部落格上的 C++ AMP 預備陣列文章。
互通性
C++ AMP 執行時間支援 類別與 Direct3D ID3D11Device 介面 之間的 accelerator_view
互通性。 create_accelerator_view 方法會採用 IUnknown
介面並傳 accelerator_view
回 物件。 get_device 方法會接受 accelerator_view
物件並傳 IUnknown
回介面。
另請參閱
C++ AMP (C++ Accelerated Massive Parallelism)
偵錯 GPU 程式碼
accelerator_view 類別