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


CPU / GPU / FPGA 性能對(duì)比
| 特性 | CPU | GPU | FPGA | ASIC |
|---|---|---|---|---|
| 靈活性 | 高 | 高 | 中 | 低 |
| 性能 | 中 | 高 | 高 | 最高 |
| 延遲 | 中 | 中 | 最低 | 最低 |
| 功耗 | 中 | 高 | 低 | 最低 |
| 開發(fā)周期 | 短 | 短 | 中 | 長(zhǎng) |
| 適用場(chǎng)景 | 通用計(jì)算 | 并行計(jì)算 | 定制加速 | 大規(guī)模部署 |
Xilinx FPGA 開發(fā)環(huán)境在 openEuler 上的安裝
# 安裝依賴dnf install -y gcc gcc-c++ make ncurses-libs libstdc++# 安裝 Vivado/Vitis./xsetup# 設(shè)置環(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# 驗(yàn)證安裝vivado -version vitis -version



04HDL 與 HLS 編程示例
在 FPGA 開發(fā)中,我經(jīng)常使用 HDL(硬件描述語(yǔ)言)和HLS(高層次綜合)兩種方法。用 HDL,比如 Verilog 或 VHDL,需要手動(dòng)描述硬件結(jié)構(gòu)和時(shí)序邏輯,能精確控制資源和性能。例如我實(shí)現(xiàn)一個(gè) 16×16 的矩陣乘法時(shí),要自己設(shè)計(jì)乘法器、累加器和流水線控制。而用 HLS,我可以直接用 C/C++ 編寫算法,像matrix_mul這樣的函數(shù)只需關(guān)注矩陣乘法邏輯,綜合工具會(huì)幫我生成帶流水線和 AXI 接口的硬件實(shí)現(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; ? ? ? ? } ? ? } }// 測(cè)試代碼#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); ? ? ? ??// 驗(yàn)證結(jié)果? ? ?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)絡(luò)加速案例
在工作中,我經(jīng)常用 FPGA 做圖像處理、加密和網(wǎng)絡(luò)加速。在圖像處理方面,我用 HLS 實(shí)現(xiàn)了 Sobel 邊緣檢測(cè),通過流水線和行緩存優(yōu)化,使高分辨率視頻幀能實(shí)時(shí)處理。在加密領(lǐng)域,我設(shè)計(jì)了 AES 和 SM4 的硬件加速模塊,讓數(shù)據(jù)加密速度比純軟件快好幾倍,同時(shí)降低了 CPU 占用。在網(wǎng)絡(luò)加速方面,我實(shí)現(xiàn)了基于 FPGA 的數(shù)據(jù)包過濾和轉(zhuǎn)發(fā)邏輯,把關(guān)鍵路徑的計(jì)算卸載到硬件上,顯著提升了吞吐量和延遲表現(xiàn)。
FPGA在圖像處理中的應(yīng)用:
// sobel_filter.cpp - Sobel邊緣檢測(cè)#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; ? ? ? ? ? ? ? ? ? ? ? ??// 計(jì)算梯度f(wàn)or?(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]; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ??// 計(jì)算梯度幅值int?grad =?abs(grad_x) +?abs(grad_y); ? ? ? ? ? ? output[y][x] = (grad >255) ?255: grad; } } }

圖像處理性能對(duì)比
| 算法 | CPU (x86) | GPU (CUDA) | FPGA (Alveo) | 延遲 |
|---|---|---|---|---|
| Sobel邊緣檢測(cè) | 45 fps | 1200 fps | 800 fps | 1.2ms |
| 高斯模糊 | 30 fps | 950 fps | 720 fps | 1.4ms |
| 形態(tài)學(xué)運(yùn)算 | 38 fps | 1100 fps | 850 fps | 1.2ms |
| 直方圖均衡 | 52 fps | 1400 fps | 900 fps | 1.1ms |
| 功耗 | 150W | 300W | 75W | - |
FPGA功耗僅為GPU的1/4,延遲更低!
加密加速
FPGA在加密算法中的應(yīng)用:
// 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輪密鑰擴(kuò)展block_tround_keys[11];#pragmaHLS ARRAY_PARTITION variable=round_keys completeexpand_key(key, round_keys); // 加密多個(gè)塊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; ? ? } }
加密性能對(duì)比
| 算法 | 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)絡(luò)加速
FPGA在網(wǎng)絡(luò)處理中的應(yīng)用:
// packet_filter.cpp - 網(wǎng)絡(luò)包過濾#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; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ? ? ? ??// 通過的包轉(zhuǎn)發(fā)if?(pass) { ? ? ? ? ? ? output.write(pkt); ? ? ? ? } ? ? } }
網(wǎng)絡(luò)加速性能對(duì)比
| 功能 | CPU | SmartNIC | FPGA | 延遲 | 吞吐量 |
|---|---|---|---|---|---|
| 包過濾 | 10 Gbps | 40 Gbps | 100 Gbps | 0.5μs | FPGA最高 |
| 負(fù)載均衡 | 8 Gbps | 35 Gbps | 80 Gbps | 0.8μs | FPGA最高 |
| DPI深度檢測(cè) | 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 - 主機(jī)代碼#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è)置參數(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總結(jié)
openEuler 多算力支持:openEuler 提供從 CPU 多核調(diào)度、GPU 加速到 FPGA/AI 加速器的支持,實(shí)現(xiàn)異構(gòu)計(jì)算協(xié)同。
FPGA 核心優(yōu)勢(shì):低延遲、低功耗、可重編程,適合圖像處理、加密和網(wǎng)絡(luò)加速。
開發(fā)便利:Vivado、Vitis、OpenCL 等工具在 openEuler 上均可使用,開發(fā)者可以直接上手。
適用場(chǎng)景:金融高頻交易、視頻編解碼、網(wǎng)絡(luò)包處理、安全加密、AI 推理等場(chǎng)景都能充分發(fā)揮多樣算力優(yōu)勢(shì)。
-
FPGA
+關(guān)注
關(guān)注
1663文章
22487瀏覽量
638691 -
cpu
+關(guān)注
關(guān)注
68文章
11319瀏覽量
225733 -
開源
+關(guān)注
關(guān)注
3文章
4306瀏覽量
46398 -
算力
+關(guān)注
關(guān)注
2文章
1643瀏覽量
16824
原文標(biāo)題:openEuler 多樣算力支持:CPU、GPU 與 FPGA 異構(gòu)加速實(shí)戰(zhàn)
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
FPGA真的能取代CPU和GPU嗎?
CPU+FPGA將作為新的異構(gòu)加速模式
什么是異構(gòu)并行計(jì)算
異構(gòu)計(jì)算的前世今生
當(dāng)CPU碰上FPGA 異構(gòu)計(jì)算又會(huì)發(fā)生什么樣的變化
FPGA為什么比CPU和GPU快
基于FPGA的異構(gòu)計(jì)算是趨勢(shì)
4家OS廠商基于openEuler發(fā)布商業(yè)發(fā)行版,加速多核異構(gòu)計(jì)算產(chǎn)業(yè)發(fā)展
CPU與GPU的區(qū)別
阿里云震旦異構(gòu)計(jì)算加速平臺(tái)基于NVIDIA Tensor Core GPU
CPU+xPU的異構(gòu)方案解析 cpu和gpu有啥區(qū)別
FPGA+GPU+CPU國(guó)產(chǎn)化人工智能平臺(tái)
基于openEuler平臺(tái)的CPU、GPU與FPGA異構(gòu)加速實(shí)戰(zhàn)
評(píng)論