学习笔记 —— C++并行库OpenMP

写在最前面:
并行化虽好,但并不是所有任务在并行化后都能得到性能的提升!
首先要满足的是所要完成的任务量远大于分配其他线程的消耗。

Installation

一般Ubuntu系统自带

Implement

1、一个最简单的OpenMP代码:

#include <iostream>
#include <omp.h>
using namespace std;
int main(){
    #pragma omp parallel default(none) shared(cout) // This is the parallel region
    {
        int ID = omp_get_thread_num();
        int num = omp_get_num_threads();
        cout << "Hello World " << ID <<  " from " << num << endl;
    }

代码编译:

命令编译方式
gcc/g++ –fopenmp hello_world.cgcc
icc/icpc –openmp hello_world.cintel (linux)
cc –openmp hello_world.cCray
pgcc –mp hello_world.cpgi

2、如何规定线程数

有三种方法,下面是当初的截图,忘了翻译了… 或者问GPT也行。
在这里插入图片描述

2、如何设置OpenMP分配线程的schedule

scheduledescription
Static(默认)Chunk-size固定,线程所执行的chunk固定
DynamicChunk-size固定,线程按需请求chunk执行
GuidedChunk-size逐渐降低,线程按需请求chunk执行

没法说哪个更好,你每个线程的任务基本一致的话static理论上比较好,如果不一致的话Dynamic和Guided可能更好。针对不同的任务需要自己测试后择优。

更详细介绍的看:
OpenMP的schedule机制

3、 冲突避免机制 --Reduction(规约)

OpenMP的reduction指令用于将计算结果从并行循环中的多个线程合并为单个结果。通过使用reduction指令,每个线程都会维护一个私有的变量,并在循环结束时将这些变量组合成单个结果。
支持多种操作符:+、-、*、/、max、min等

使用OpenMP的reduction指令计算向量中所有元素的和的示例:

#include<omp.h>
#include<stdio.h>
#include<stdlib.h>

#define SIZE 10000000

int main() {
    int i;
    double sum = 0.0;
    double *array = (double*) malloc(SIZE * sizeof(double));

    // 初始化数组
    for (i = 0; i < SIZE; i++) {
        array[i] = i * 0.1;
    }

    // 使用OpenMP并行计算数组总和
#pragma omp parallel for default(none) reduction(+: sum)
    for (i = 0; i < SIZE; i++) {
        sum += array[i];
    }

    printf("Sum of array elements = %lf\n", sum);

    free(array);
    return 0;
}

上例中,通过使用#pragma omp parallel for reduction(+: sum)指令,将计算数组所有元素总和的任务划分给多个线程并使用加法操作符(+)将每个线程私有的sum变量的值累加到共享的sum变量中,最终输出结果的正确和最终值。

Discovery

另外经过实验我发现,针对同一代码,使用C编译和C++编译得到的性能是不同的。
如针对下面这个计算圆周率 π \pi π的例子:
在这里插入图片描述

相关理论在这:

现在来看下随着使用的线程数增加,我们的运算耗时如何变化:

PC的CPU: AMD 5800H

在这里插入图片描述
C++编译后的性能变化趋势如下:
在这里插入图片描述
可以看到,C的结果与我们的预想基本一致,线程数越大运算越快;线程数大到一定程度速度就不怎么增加了。
而C++的结果却出乎意料,但仅就耗时的数量级来看,C++的性能是远高于C的。我暂时还不能解释原因…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昼行plus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值