OpenMP(Open Multi-Processing)是共享記憶體並行編程的事實標準,憑藉「指令式」設計,讓 C/C++/Fortran 開發者以最小代價釋放多核效能。本文系統梳理核心指令、執行時 API、編譯鏈配置,並附帶完整可運行範例,助你快速上手 Linux 平台下的並行開發。
| 指令 | 語法範例 | 功能說明 |
|---|---|---|
| parallel for | #pragma omp parallel for | 將迴圈迭代分配給多線程並行執行 |
| for reduction | #pragma omp for reduction(+:sum) | 線程私有變量計算後自動歸約(求和/乘積等) |
| critical | #pragma omp critical { ... } | 互斥區塊,同一時間僅一線程進入 |
| parallel for private | #pragma omp parallel for private(x,y) | 指定變量為線程私有,各線程擁有獨立副本 |
| schedule | #pragma omp parallel for schedule(dynamic, 4) | 迭代調度策略:static/dynamic/guided,塊大小可調 |
| parallel sections | #pragma omp parallel sections { #pragma omp section ... } | 不同代碼區塊並行執行,需無數據依賴 |
| master / single | #pragma omp master { ... } | 僅主線程/單一線程執行,single 隱含 barrier |
| barrier / nowait | #pragma omp barrier | 線程同步屏障 / 取消隱含同步 |
| firstprivate / lastprivate | #pragma omp parallel for firstprivate(val) | 線程入口賦初值 / 出口將最後迭代值回傳主線程 |
| 函數 | 功能 | 典型用途 |
|---|---|---|
omp_get_num_threads() | 獲取當前團隊線程數 | 動態調整演算法行為 |
omp_set_num_threads(n) | 設定後續並行區線程數 | 程式啟動時根據 CPU 核心數配置 |
omp_get_thread_num() | 獲取當前線程 ID (0~n-1) | 線程專屬邏輯分支 |
omp_get_num_procs() | 獲取可用處理器核心數 | 自動適配硬體資源 |
omp_demo.c#include <stdio.h>
#include <omp.h>
int main() {
int rank, size;
// 方式 1:pragma 指定線程數
#pragma omp parallel num_threads(3) private(rank)
{
rank = omp_get_thread_num();
size = omp_get_num_threads();
printf("Thread %d of %d: Hello OpenMP!\n", rank, size);
}
// 方式 2:API 設定線程數
omp_set_num_threads(2);
#pragma omp parallel private(rank)
{
rank = omp_get_thread_num();
size = omp_get_num_threads();
printf("API mode - Thread %d of %d\n", rank, size);
}
return 0;
}
# Ubuntu/Debian 系統通常無需額外安裝,GCC 內建支援
gcc -fopenmp -o omp_demo omp_demo.c
# 執行
./omp_demo
Thread 0 of 3: Hello OpenMP!
Thread 1 of 3: Hello OpenMP!
Thread 2 of 3: Hello OpenMP!
API mode - Thread 0 of 2
API mode - Thread 1 of 2
export OMP_NUM_THREADS=4 # 設定預設線程數
export OMP_SCHEDULE="dynamic,2" # 設定預設調度策略
export OMP_PROC_BIND=true # 線程綁核,提升緩存命中率
private 導致競爭條件,善用 default(none) 強制顯式聲明padding 或 alignas(64) 對齊omp_set_nested(1) 或 OMP_NESTED=true 啟用libgomp 或 libiomp5schedule(static) 靜態負載均衡,負載不均時改 dynamic 或 guidedcollapse(n) 將多層巢狀迴圈攤平並行SIMD 指令:#pragma omp simd 或 #pragma omp parallel for simdperf、VTune 分析負載不平衡、鎖爭用、緩存未命中核心心法: OpenMP 讓並行「聲明式」化——專注於「什麼可以並行」,而非「如何管理線程」。善用編譯器與運行時,少寫代碼,多跑效能。