OpenMP并行开发 (C++)

OpenMP是一种用于共享内存并行系统的多线程编程框架,支持C、C++和Fortran。它通过pragma指令简化了并行编程,采用fork-join执行模式,允许并行执行代码段、for循环等。文章介绍了OpenMP的基本概念、执行模式、主要指令以及如何在CMakeLists.txt中配置和在C++程序中使用OpenMP进行并行处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. OpenMP基本概念

OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C、C++和Fortran。OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用OpenMP降低了并行编程的难度和复杂度。当编译器不支持OpenMP时,程序会退化成普通(串行)程序。程序中已有的OpenMP指令不会影响程序的正常编译运行。

2. OpenMP执行模式

OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。

一个典型的fork-join执行模型的示意图如下:

3. OpenMP的指令

OpenMP的指令有以下一些:(常用的已标黑)

  • parallel,用在一个代码段之前,表示这段代码将被多个线程并行执行
  • for,用于for循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性。
  • parallel for,parallel和for语句的结合,也是用在一个for循环之前,表示for循环的代码将被多个线程并行执行
  • sections,用在可能会被并行执行的代码段之前
  • parallel sections,parallel和sections两个语句的结合
  • critical,用在一段代码临界区之前
  • single,用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执行
  • flush,用以标记一个同步点,用以确保所有的线程看到一致的存储器视图
  • barrier,用于并行区内代码的线程同步,所有线程执行到barrier时要停止,直到所有线程都执行到barrier时才继续往下执行
  • atomic,用于指定一块内存区域被制动更新
  • master,用于指定一段代码块由主线程执行
  • ordered,用于指定并行区域的循环按顺序执行
  • threadprivate,用于指定一个变量是线程私有的

4. 安装

安装libgomp1包:

sudo apt install libgomp1

安装libomp-dev包: 

sudo apt install libomp-dev

5. CMakeLists.txt编写

find_package(OpenMP REQUIRED)  
target_link_libraries({project_name} OpenMP::OpenMP_CXX)

6. 使用

6.1. parallel

#include <iostream>
#include "omp.h"

using namespace std;

int main(int argc, char **argv) {
	//设置线程数,一般设置的线程数不超过CPU核心数,这里开4个线程执行并行代码段
	omp_set_num_threads(4);
    #pragma omp parallel
	{
		cout << "Hello" << ", I am Thread " << omp_get_thread_num() << endl;
	}
}

输出:

Hello, I am Thread 1
Hello, I am Thread 0
Hello, I am Thread 2
Hello, I am Thread 3

可以看到,OpenMP自动用4个线程调用了代码。

6.2. parallel用于for循环

#include <iostream>
#include "omp.h"

using namespace std;

int main() {
    omp_set_num_threads(4);
    #pragma omp parallel
    for (int i = 0; i < 3; i++) {
        printf("i = %d, I am Thread %d\n", i, omp_get_thread_num());
    }
    getchar();
}

输出:

i = 0, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 0, I am Thread 0
i = 0, I am Thread 0
i = 0, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0

6.2. parallel for用于for循环

#include <iostream>
#include "omp.h"

using namespace std;

int main() {
    omp_set_num_threads(4);
    #pragma omp parallel for
    for (int i = 0; i < 3; i++) {
        printf("i = %d, I am Thread %d\n", i, omp_get_thread_num());
    }
    getchar();
}

输出:

i = 0, I am Thread 0
i = 1, I am Thread 1
i = 2, I am Thread 2 

参考文献

OpenMP并行开发(C++) - 知乎

OpenMP简介_c++openmp_longji的博客-CSDN博客

OpenMP用法大全(个人整理版)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值