01開篇導語
隨著 AI、視頻處理、加密和高性能計算需求的增長,單一 CPU 已無法滿足低延遲、高吞吐量的計算需求。openEuler 作為面向企業(yè)和云端的開源操作系統(tǒng),在多樣算力支持方面表現(xiàn)出色,能夠高效調(diào)度 CPU、GPU、FPGA 及 AI 加速器,實現(xiàn)異構計算協(xié)同。
本文我將結合 openEuler 平臺,介紹 CPU、GPU 與 FPGA 的異構計算能力,并展示在圖像處理、加密和網(wǎng)絡加速中的實際應用。
02多樣算力支持概覽
openEuler 對多樣算力的支持主要體現(xiàn)在以下幾個方面:
CPU 多核優(yōu)化:openEuler 內(nèi)核對多核 CPU 調(diào)度和 NUMA 拓撲優(yōu)化良好,保證高性能計算任務的并行效率。
GPU 加速:通過 CUDA、OpenCL 等接口,openEuler 可以直接調(diào)度 GPU 進行浮點計算、圖像處理和深度學習任務。
FPGA/AI 加速器:openEuler 支持 FPGA 管理器、DMA 設備和 OpenCL 運行環(huán)境,可用于低延遲加速和定制硬件計算。
異構計算協(xié)同:通過 openEuler 的任務調(diào)度和驅(qū)動支持,可以實現(xiàn) CPU/GPU/FPGA 的混合調(diào)用,充分利用硬件資源。
03FPGA 在 openEuler 上的支持
FPGA 是典型的異構計算單元,低延遲、低功耗、高靈活性。在 openEuler 上可以通過/dev/xdma*和/sys/class/fpga_manager/管理 FPGA 設備,并使用 Vivado/Vitis 或 OpenCL 進行開發(fā)。
# 檢測 FPGA 設備 lspci |grep-i fpga lspci |grep-i xilinx lspci |grep-i altera # 查看 FPGA 設備信息 ls -la/dev/xdma* ls -la/sys/class/fpga_manager/


CPU / GPU / FPGA 性能對比
| 特性 | CPU | GPU | FPGA | ASIC |
|---|---|---|---|---|
| 靈活性 | 高 | 高 | 中 | 低 |
| 性能 | 中 | 高 | 高 | 最高 |
| 延遲 | 中 | 中 | 最低 | 最低 |
| 功耗 | 中 | 高 | 低 | 最低 |
| 開發(fā)周期 | 短 | 短 | 中 | 長 |
| 適用場景 | 通用計算 | 并行計算 | 定制加速 | 大規(guī)模部署 |
Xilinx FPGA 開發(fā)環(huán)境在 openEuler 上的安裝
# 安裝依賴dnf install -y gcc gcc-c++ make ncurses-libs libstdc++# 安裝 Vivado/Vitis./xsetup# 設置環(huán)境變量exportXILINX_VIVADO=/tools/Xilinx/Vivado/2023.1exportXILINX_VITIS=/tools/Xilinx/Vitis/2023.1exportPATH=$XILINX_VIVADO/bin:$XILINX_VITIS/bin:$PATHsource$XILINX_VIVADO/settings64.sh# 驗證安裝vivado -version vitis -version



04HDL 與 HLS 編程示例
在 FPGA 開發(fā)中,我經(jīng)常使用 HDL(硬件描述語言)和HLS(高層次綜合)兩種方法。用 HDL,比如 Verilog 或 VHDL,需要手動描述硬件結構和時序邏輯,能精確控制資源和性能。例如我實現(xiàn)一個 16×16 的矩陣乘法時,要自己設計乘法器、累加器和流水線控制。而用 HLS,我可以直接用 C/C++ 編寫算法,像matrix_mul這樣的函數(shù)只需關注矩陣乘法邏輯,綜合工具會幫我生成帶流水線和 AXI 接口的硬件實現(xiàn),這大大加快了我的開發(fā)效率,也讓我能更專注于算法優(yōu)化。
使用C/C++編寫FPGA程序:
// matrix_mul.cpp - 矩陣乘法HLS#include#defineN 16voidmatrix_mul( int A[N][N], int B[N][N], int C[N][N]){#pragmaHLS INTERFACE m_axi port=A offset=slave bundle=gmem0#pragmaHLS INTERFACE m_axi port=B offset=slave bundle=gmem1#pragmaHLS INTERFACE m_axi port=C offset=slave bundle=gmem2#pragmaHLS INTERFACE s_axilite port=return// 矩陣乘法for(inti =0; i < N; i++) { ? ? ? ?for?(int?j =?0; j < N; j++) {#pragma?HLS PIPELINE II=1int?sum =?0; ? ? ? ? ? ?for?(int?k =?0; k < N; k++) { ? ? ? ? ? ? ? ? sum += A[i][k] * B[k][j]; ? ? ? ? ? ? } ? ? ? ? ? ? C[i][j] = sum; ? ? ? ? } ? ? } }// 測試代碼#include intmain(){ intA[N][N], B[N][N], C[N][N]; // 初始化矩陣for(inti =0; i < N; i++) { ? ? ? ?for?(int?j =?0; j < N; j++) { ? ? ? ? ? ? A[i][j] = i + j; ? ? ? ? ? ? B[i][j] = i - j; ? ? ? ? } ? ? } ? ? ? ??// 調(diào)用硬件函數(shù)matrix_mul(A, B, C); ? ? ? ??// 驗證結果? ? ?std::cout <"C[0][0] = "?<< C[0][0] << std::endl; ? ? ? ??return0; }
# HLS綜合vitis_hls -f run_hls.tcl# run_hls.tcl內(nèi)容# open_project matrix_mul_proj# set_top matrix_mul# add_files matrix_mul.cpp# add_files -tb matrix_mul_tb.cpp# open_solution "solution1"# set_part {xcvu9p-flga2104-2-i}# create_clock -period 10 -name default# csim_design# csynth_design# cosim_design# export_design -format ip_catalog

HLS優(yōu)化指令
| 指令 | 作用 | 示例 | 效果 |
|---|---|---|---|
| PIPELINE | 流水線 | #pragmaHLS PIPELINE II=1 | 吞吐量提升10x |
| UNROLL | 循環(huán)展開 | #pragmaHLS UNROLL factor=4 | 并行度提升4x |
| ARRAY_PARTITION | 數(shù)組分割 | #pragmaHLS ARRAY_PARTITION | 帶寬提升 |
| DATAFLOW | 數(shù)據(jù)流 | #pragmaHLS DATAFLOW | 延遲降低50% |
| INLINE | 函數(shù)內(nèi)聯(lián) | #pragmaHLS INLINE | 減少開銷 |
05圖像處理、加密與網(wǎng)絡加速案例
在工作中,我經(jīng)常用 FPGA 做圖像處理、加密和網(wǎng)絡加速。在圖像處理方面,我用 HLS 實現(xiàn)了 Sobel 邊緣檢測,通過流水線和行緩存優(yōu)化,使高分辨率視頻幀能實時處理。在加密領域,我設計了 AES 和 SM4 的硬件加速模塊,讓數(shù)據(jù)加密速度比純軟件快好幾倍,同時降低了 CPU 占用。在網(wǎng)絡加速方面,我實現(xiàn)了基于 FPGA 的數(shù)據(jù)包過濾和轉發(fā)邏輯,把關鍵路徑的計算卸載到硬件上,顯著提升了吞吐量和延遲表現(xiàn)。
FPGA在圖像處理中的應用:
// sobel_filter.cpp - Sobel邊緣檢測#include#include #defineWIDTH 1920#defineHEIGHT 1080typedefap_uint<8>pixel_t;voidsobel_filter( pixel_t input[HEIGHT][WIDTH], pixel_t output[HEIGHT][WIDTH]){#pragmaHLS INTERFACE m_axi port=input offset=slave bundle=gmem0#pragmaHLS INTERFACE m_axi port=output offset=slave bundle=gmem1#pragmaHLS INTERFACE s_axilite port=return// Sobel算子constintGx[3][3] = {{-1,0,1}, {-2,0,2}, {-1,0,1}}; constintGy[3][3] = {{-1,-2,-1}, {0,0,0}, {1,2,1}}; // 行緩存pixel_tline_buf[2][WIDTH];#pragmaHLS ARRAY_PARTITION variable=line_buf complete dim=1for(inty =1; y < HEIGHT -?1; y++) { ? ? ? ?for?(int?x =?1; x < WIDTH -?1; x++) {#pragma?HLS PIPELINE II=1int?grad_x =?0, grad_y =?0; ? ? ? ? ? ? ? ? ? ? ? ??// 計算梯度for?(int?i =?-1; i <=?1; i++) { ? ? ? ? ? ? ? ?for?(int?j =?-1; j <=?1; j++) { ? ? ? ? ? ? ? ? ? ?pixel_t?pixel = input[y+i][x+j]; ? ? ? ? ? ? ? ? ? ? grad_x += pixel * Gx[i+1][j+1]; ? ? ? ? ? ? ? ? ? ? grad_y += pixel * Gy[i+1][j+1]; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ??// 計算梯度幅值int?grad =?abs(grad_x) +?abs(grad_y); ? ? ? ? ? ? output[y][x] = (grad >255) ?255: grad; } } }

圖像處理性能對比
| 算法 | CPU (x86) | GPU (CUDA) | FPGA (Alveo) | 延遲 |
|---|---|---|---|---|
| Sobel邊緣檢測 | 45 fps | 1200 fps | 800 fps | 1.2ms |
| 高斯模糊 | 30 fps | 950 fps | 720 fps | 1.4ms |
| 形態(tài)學運算 | 38 fps | 1100 fps | 850 fps | 1.2ms |
| 直方圖均衡 | 52 fps | 1400 fps | 900 fps | 1.1ms |
| 功耗 | 150W | 300W | 75W | - |
FPGA功耗僅為GPU的1/4,延遲更低!
加密加速
FPGA在加密算法中的應用:
// aes_encrypt.cpp - AES加密加速#includetypedefap_uint<128>block_t;typedefap_uint<8>byte_t;voidaes_encrypt( block_t plaintext[1024], block_t key, block_t ciphertext[1024], int num_blocks){#pragmaHLS INTERFACE m_axi port=plaintext offset=slave bundle=gmem0#pragmaHLS INTERFACE m_axi port=ciphertext offset=slave bundle=gmem1#pragmaHLS INTERFACE s_axilite port=key#pragmaHLS INTERFACE s_axilite port=num_blocks#pragmaHLS INTERFACE s_axilite port=return// AES輪密鑰擴展block_tround_keys[11];#pragmaHLS ARRAY_PARTITION variable=round_keys completeexpand_key(key, round_keys); // 加密多個塊for(inti =0; i < num_blocks; i++) {#pragma?HLS PIPELINE II=1block_t?state = plaintext[i]; ? ? ? ? ? ? ? ??// 初始輪密鑰加? ? ? ? ?state ^= round_keys[0]; ? ? ? ? ? ? ? ??// 9輪加密for?(int?round =?1; round 10; round++) {#pragma?HLS UNROLL? ? ? ? ? ? ?state =?sub_bytes(state); ? ? ? ? ? ? state =?shift_rows(state); ? ? ? ? ? ? state =?mix_columns(state); ? ? ? ? ? ? state ^= round_keys[round]; ? ? ? ? } ? ? ? ? ? ? ? ??// 最后一輪? ? ? ? ?state =?sub_bytes(state); ? ? ? ? state =?shift_rows(state); ? ? ? ? state ^= round_keys[10]; ? ? ? ? ? ? ? ? ?ciphertext[i] = state; ? ? } }
加密性能對比
| 算法 | CPU | GPU | FPGA | 吞吐量 | 延遲 |
|---|---|---|---|---|---|
| AES-128 | 2.3 Gbps | 45 Gbps | 100 Gbps | FPGA最高 | 0.5μs |
| AES-256 | 1.8 Gbps | 38 Gbps | 85 Gbps | FPGA最高 | 0.6μs |
| RSA-2048 | 1200 ops/s | 25K ops/s | 50K ops/s | FPGA最高 | 20μs |
| SHA-256 | 850 MB/s | 12 GB/s | 25 GB/s | FPGA最高 | 0.3μs |
網(wǎng)絡加速
FPGA在網(wǎng)絡處理中的應用:
// packet_filter.cpp - 網(wǎng)絡包過濾#include#include typedefap_uint<512>packet_t; // 64字節(jié)包typedefap_uint<32>ip_addr_t;structpacket_header{ ip_addr_tsrc_ip; ip_addr_tdst_ip; ap_uint<16> src_port; ap_uint<16> dst_port; ap_uint<8> protocol; };voidpacket_filter( hls::stream &input, hls::stream &output, ip_addr_t whitelist[256], int whitelist_size){#pragmaHLS INTERFACE axis port=input#pragmaHLS INTERFACE axis port=output#pragmaHLS INTERFACE s_axilite port=whitelist#pragmaHLS INTERFACE s_axilite port=whitelist_size#pragmaHLS INTERFACE s_axilite port=return#pragmaHLS PIPELINE II=1while(!input.empty()) { packet_tpkt = input.read(); // 解析包頭 packet_header hdr; hdr.src_ip = pkt.range(31,0); hdr.dst_ip = pkt.range(63,32); hdr.src_port = pkt.range(79,64); hdr.dst_port = pkt.range(95,80); hdr.protocol = pkt.range(103,96); // 檢查白名單boolpass =false; for(inti =0; i < whitelist_size; i++) {#pragma?HLS UNROLL factor=16if?(hdr.src_ip == whitelist[i]) { ? ? ? ? ? ? ? ? pass =?true; ? ? ? ? ? ? ? ?break; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ? ? ? ??// 通過的包轉發(fā)if?(pass) { ? ? ? ? ? ? output.write(pkt); ? ? ? ? } ? ? } }
網(wǎng)絡加速性能對比
| 功能 | CPU | SmartNIC | FPGA | 延遲 | 吞吐量 |
|---|---|---|---|---|---|
| 包過濾 | 10 Gbps | 40 Gbps | 100 Gbps | 0.5μs | FPGA最高 |
| 負載均衡 | 8 Gbps | 35 Gbps | 80 Gbps | 0.8μs | FPGA最高 |
| DPI深度檢測 | 5 Gbps | 25 Gbps | 60 Gbps | 1.2μs | FPGA最高 |
| IPsec加密 | 3 Gbps | 20 Gbps | 50 Gbps | 2.0μs | FPGA最高 |
OpenCL編程
使用OpenCL編寫FPGA程序:
// vector_add.cl - OpenCL向量加法__kernel voidvector_add( __global constfloat *a, __global constfloat *b, __global float *c, constint n){ intgid =get_global_id(0); if(gid < n) { ? ? ? ? c[gid] = a[gid] + b[gid]; ? ? } }
// host.cpp - 主機代碼#include#include intmain(){ constintN =1024; // 初始化OpenCL cl_platform_id platform; clGetPlatformIDs(1, &platform,NULL); cl_device_id device; clGetDeviceIDs(platform, CL_DEVICE_TYPE_ACCELERATOR,1, &device,NULL); cl_context context =clCreateContext(NULL,1, &device,NULL,NULL,NULL); cl_command_queue queue =clCreateCommandQueue(context, device,0,NULL); // 加載內(nèi)核 FILE *fp =fopen("vector_add.xclbin","rb"); fseek(fp,0, SEEK_END); size_tbinary_size =ftell(fp); rewind(fp); unsignedchar*binary =newunsignedchar[binary_size]; fread(binary,1, binary_size, fp); fclose(fp); cl_program program =clCreateProgramWithBinary(context,1, &device, &binary_size, (constunsignedchar**)&binary, NULL,NULL); clBuildProgram(program,1, &device,NULL,NULL,NULL); cl_kernel kernel =clCreateKernel(program,"vector_add",NULL); // 分配內(nèi)存float*h_a =newfloat[N]; float*h_b =newfloat[N]; float*h_c =newfloat[N]; for(inti =0; i < N; i++) { ? ? ? ? h_a[i] = i *?1.0f; ? ? ? ? h_b[i] = i *?2.0f; ? ? } ? ? ? ? ?cl_mem d_a =?clCreateBuffer(context, CL_MEM_READ_ONLY, N *?sizeof(float),?NULL,?NULL); ? ? cl_mem d_b =?clCreateBuffer(context, CL_MEM_READ_ONLY, N *?sizeof(float),?NULL,?NULL); ? ? cl_mem d_c =?clCreateBuffer(context, CL_MEM_WRITE_ONLY, N *?sizeof(float),?NULL,?NULL); ? ? ? ??clEnqueueWriteBuffer(queue, d_a, CL_TRUE,?0, N *?sizeof(float), h_a,?0,?NULL,?NULL); ? ?clEnqueueWriteBuffer(queue, d_b, CL_TRUE,?0, N *?sizeof(float), h_b,?0,?NULL,?NULL); ? ? ? ??// 設置參數(shù)并執(zhí)行clSetKernelArg(kernel,?0,?sizeof(cl_mem), &d_a); ? ?clSetKernelArg(kernel,?1,?sizeof(cl_mem), &d_b); ? ?clSetKernelArg(kernel,?2,?sizeof(cl_mem), &d_c); ? ?clSetKernelArg(kernel,?3,?sizeof(int), &N); ? ? ? ??size_t?global_size = N; ? ?clEnqueueNDRangeKernel(queue, kernel,?1,?NULL, &global_size,?NULL,?0,?NULL,?NULL); ? ? ? ??clEnqueueReadBuffer(queue, d_c, CL_TRUE,?0, N *?sizeof(float), h_c,?0,?NULL,?NULL); ? ? ? ? ?std::cout <"Result: "?<< h_c[0] << std::endl; ? ? ? ??// 清理delete[] h_a;?delete[] h_b;?delete[] h_c; ? ?clReleaseMemObject(d_a);?clReleaseMemObject(d_b);?clReleaseMemObject(d_c); ? ?clReleaseKernel(kernel); ? ?clReleaseProgram(program); ? ?clReleaseCommandQueue(queue); ? ?clReleaseContext(context); ? ? ? ??return0; }

06總結
openEuler 多算力支持:openEuler 提供從 CPU 多核調(diào)度、GPU 加速到 FPGA/AI 加速器的支持,實現(xiàn)異構計算協(xié)同。
FPGA 核心優(yōu)勢:低延遲、低功耗、可重編程,適合圖像處理、加密和網(wǎng)絡加速。
開發(fā)便利:Vivado、Vitis、OpenCL 等工具在 openEuler 上均可使用,開發(fā)者可以直接上手。
適用場景:金融高頻交易、視頻編解碼、網(wǎng)絡包處理、安全加密、AI 推理等場景都能充分發(fā)揮多樣算力優(yōu)勢。
-
FPGA
+關注
關注
1662文章
22474瀏覽量
638340 -
cpu
+關注
關注
68文章
11311瀏覽量
225645 -
開源
+關注
關注
3文章
4287瀏覽量
46358 -
算力
+關注
關注
2文章
1612瀏覽量
16816
原文標題:openEuler 多樣算力支持:CPU、GPU 與 FPGA 異構加速實戰(zhàn)
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
FPGA真的能取代CPU和GPU嗎?
CPU+FPGA將作為新的異構加速模式
什么是異構并行計算
異構計算的前世今生
當CPU碰上FPGA 異構計算又會發(fā)生什么樣的變化
FPGA為什么比CPU和GPU快
基于FPGA的異構計算是趨勢
4家OS廠商基于openEuler發(fā)布商業(yè)發(fā)行版,加速多核異構計算產(chǎn)業(yè)發(fā)展
阿里云震旦異構計算加速平臺基于NVIDIA Tensor Core GPU
CPU+xPU的異構方案解析 cpu和gpu有啥區(qū)別
基于openEuler平臺的CPU、GPU與FPGA異構加速實戰(zhàn)
評論