C++異構程式設計:Data Parallel C++(DPC++)

現代工作負載多樣性導致了對體系結構多樣性的需求;沒有一種體系結構是適合每種工作負載的。為了提取所需的效能,需要在CPU、GPU、AI

引擎

和FPGA加速器中部署標量、向量、矩陣和空間(SVMS)架構的混合。

它將整合一組開發人員工具,提供統一的程式設計模型,從而簡化跨“不同架構”中工作負載的開發。

oneAPI程式設計模型支援兩種異構計算方法:資料並行DPC++和OpenMP*(*表示多種語言)

DPC++是一種開源語言,基於現代C++和來自Khronos* Group的SYCL*語言,帶有一些額外的Intel擴充套件。

OpenMP作為一種標準程式語言已經有20多年的歷史了,Intel實現了OpenMP標準的5。0版本。

不支援FPGA裝置。

SYCL是Khronos Group針對OpenCL的單源異構程式設計。它是一個基於OpenCL構建的跨平臺抽象層,因此異構處理器的程式碼可以使用普通的C++以單源方式編寫。 SYCL提供的優點是應用程式的主機和裝置程式碼以型別安全的方式包含在同一原始檔中,並使用跨平臺非同步任務。 SYCL附帶模板和泛型lambda函式。

HPC++程式設計模型

在異構計算中,主處理器利用加速器裝置來更有效地執行程式碼。

一個原始檔:主機

程式碼和解除安裝到

加速器裝置

程式碼都合併在一個原始檔中。

語法是標準的C++

:沒有任何新的關鍵字或語法用來表示並行性。相反,並行性是透過C++類來表達的。

#include #include constexpr int num=16;//using namespace sycl;int main() { // 建立一個包含16個int型別元素的緩衝區 auto r = sycl::range{num}; sycl::buffer a{r}; // buffer類表示將被解除安裝到裝置的資料快取 // 這個簡單的示例要求DPC++選擇一個預設的加速器裝置,但是一個更健壯的應用程式可能會檢查系統的拓撲並選擇一個特定的加速器。 // 這個submit()函式的引數是一個lambda函式,它在主機上立即執行。 sycl::queue{}。submit([&](sycl::handler& h) { // queue類表示從主機到加速器的連線 sycl::accessor out{a, h}; //建立一個訪問器 // 對parallel_for()的呼叫有兩個引數。一個引數是lambda函式,另一個引數是表示緩衝區中元素數量的範圍物件“r”。DPC++安排這個lambda在這個範圍內的每個索引上在加速器上被呼叫一次。 h。parallel_for(r, [=](sycl::item<1> idx) { out[idx] = idx; }); }); // 呼叫parallel_for()之後,程式碼的主機部分繼續執行,而無需等待加速器上的工作完成。 //主機做的下一件事是建立一個host_accessor,它讀取緩衝區的元素。 // DPC++知道這個緩衝區是由加速器寫的,所以host_accessor建構函式阻塞,直到parallel_for()提交的工作完成。 sycl::host_accessor result{a}; for (int i=0; i

編譯執行

dpcpp -I%MKLROOT%/include /EHsc -c simple。cpp /Fosimple。obj

dpcpp simple。obj -fsycl-device-code-split=per_kernel sycl。lib OpenCL。lib -o simple。exe

C++異構程式設計:Data Parallel C++(DPC++)

使用BLAS(Basic Linear Algebra Subprograms 基礎線性代數程式集)

#include // std::vector()#include // std::rand()#include #include “oneapi/mkl/blas。hpp”int main(int argc, char* argv[]) { double alpha = 2。0; int n_elements = 1024; int incx = 1; std::vector x; x。resize(incx * n_elements); for (int i=0; i y; y。resize(incy * n_elements); for (int i=0; i x_buffer(x。data(), x。size()); cl::sycl::buffer y_buffer(y。data(), y。size()); // perform y = alpha*x + y try { oneapi::mkl::blas::axpy(my_queue, n_elements, alpha, x_buffer, incx, y_buffer, incy); } catch(cl::sycl::exception const& e) { std::cout << “\t\tCaught synchronous SYCL exception:\n” << e。what() << std::endl; } std::cout << “The axpy (y = alpha * x + y) computation is complete!” << std::endl; // print y_buffer auto y_accessor = y_buffer。template get_access(); std::cout << std::endl; std::cout << “y” << “ = [ ” << y_accessor[0] << “ ]\n”; std::cout << “ [ ” << y_accessor[1*incy] << “ ]\n”; std::cout << “ [ ” << “。。。 ]\n”; std::cout << std::endl; return 0;}

編譯執行

dpcpp -I%MKLROOT%/include /EHsc -c axpy。cpp /Foaxpy。obj

dpcpp axpy。obj -fsycl-device-code-split=per_kernel %MKLROOT%/lib/intel64/mkl_sycl。lib %MKLROOT%/lib/intel64/mkl_intel_ilp64。lib “%MKLROOT%”/lib/intel64/mkl_sequential。lib %MKLROOT%/lib/intel64/mkl_core。lib sycl。lib OpenCL。lib -o axpy。exe

C++異構程式設計:Data Parallel C++(DPC++)

oneAPI程式設計指南:

https://software。intel。com/content/www/us/en/develop/documentation/oneapi-programming-guide/top。html

DPC++參考手冊

https://software。intel。com/content/www/cn/zh/develop/tools/oneapi/data-parallel-c-plus-plus。html#gs。56b30v

《Data Parallel C++

《Data Parallel C++: Mastering DPC++ for Programming of Heterogeneous Systems using C++ and SYCL》

https://link。springer。com/book/10。1007%2F978-1-4842-5574-2