歡迎關注我的公衆号 [極智視界],擷取我的更多筆記分享
大家好,我是極智視界,本文講解一下 OpenMP 多線程使用方法。
OpenMP 是一種用于共享記憶體并行系統的多線程程式設計方案,其提供了對并行算法的高層抽象描述,特别适合在多核 CPU 機器上的并行程式設計。編譯器根據程式中添加的 pragma 指令,自動将程式并行處理,使用 OpenMP 降低了并行程式設計的難度和複雜度。當編譯器不支援 OpenMP 時,程式會退化成普通(串行)程式,程式中已有的 OpenMP 指令不會影響程式的正常編譯運作。
文章目錄
- 1 OpenMP 常用指令
- 2 OpenMP 使用示例
1 OpenMP 常用指令
使用 OpenMP 時需要引入
omp.h
頭檔案,然後在編譯時添加參數
-fopenmp
即可。在具體需要進行并行運算的部分,使用
#pragma omp
指令[子句] 來告訴編譯器如何并行執行對應的語句。
常用的指令如下:
- parallel:即
後面需要有一個代碼片段,使用#pragma omp parallel
括起來,表示會被并行執行;{}
- parallel for:這裡後面接
語句即可,不需要有額外的代碼塊;for
- sections;
- parallel sections;
- single:表示隻能單線程執行;
- critical:臨界區,表示每次隻能有一個 openmp 線程進入;
- barrier:用于并行域内代碼的線程同步,線程執行到 barrier 時停下來,直到所有線程都執行到barrier時才繼續;
常用的子句如下:
- num_threads:指定并行域内線程的數目;
- shared:指定一個或者多個變量為多個線程的共享變量;
- private:指定一個變量或者多個變量在每個線程中都有它的副本;
另外,openmp 還提供了一些列的 API 函數來擷取并行線程的狀态或控制并行線程的行為,常用 API 如下:
- omp_in_parallel:判斷目前是否在并行域中;
- omp_get_thread_num:擷取線程号;
- omp_set_num_threads:設定并行域中線程格式;
- omp_get_num_threads:傳回并行域中線程數;
- omp_get_dynamic:判斷是否支援動态改變線程數目;
- omp_get_max_threads: 擷取并行域中可用的最大的并行線程數目;
- omp_get_num_procs:傳回系統中處理器的個數;
2 OpenMP 使用示例
這裡介紹一個計算圓周率的示例:
#include <stdio.h>
#include <omp.h>
#define MAX_THREADS 4
static long num_steps = 100000000;
double step;
int spmd(){
int i,j;
double pi, full_sum = 0.0;
double start_time, run_time;
double sum[MAX_THREADS];
step = 1.0/(double) num_steps;
for(j=1;j<=MAX_THREADS ;j++){
omp_set_num_threads(j);
full_sum = 0.0;
start_time = omp_get_wtime();
#pragma omp parallel private(i)
{
int id = omp_get_thread_num();
int numthreads = omp_get_num_threads();
double x;
double partial_sum = 0;
#pragma omp single
printf(" num_threads = %d",numthreads);
for (i=id;i< num_steps; i+=numthreads){
x = (i+0.5)*step;
partial_sum += + 4.0/(1.0+x*x);
}
#pragma omp critical
full_sum += partial_sum;
}
pi = step * full_sum;
run_time = omp_get_wtime() - start_time;
printf("\n pi is %f in %f seconds %d threds \n ",pi,run_time,j);
}
}
int openMP(){
int i;
double x, pi, sum = 0.0;
double start_time, run_time;
step = 1.0/(double) num_steps;
for (i=1;i<=4;i++){
sum = 0.0;
omp_set_num_threads(i);
start_time = omp_get_wtime();
#pragma omp parallel
{
#pragma omp single
printf(" num_threads = %d",omp_get_num_threads());
#pragma omp for reduction(+:sum)
for (i=1;i<= num_steps; i++){
x = (i-0.5)*step;
sum = sum + 4.0/(1.0+x*x);
}
}
pi = step * sum;
run_time = omp_get_wtime() - start_time;
printf("\n pi is %f in %f seconds and %d threads\n",pi,run_time,i);
}
}
int main() {
spmd();
printf("openMP Loop Paralelism:\n");
openMP();
return 0;
}
運作結果如下:
好了,以上分享了 OpenMP 多線程使用方法。希望我的分享能對你的學習有一點幫助。