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

Contents

  • Installation
  • Implement
      • 1、一个最简单的OpenMP代码:
      • 2、如何规定线程数
      • 2、如何设置OpenMP分配线程的schedule
      • 3、 冲突避免机制 --Reduction(规约)
  • Discovery

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

Installation

一般Ubuntu系统自带

Implement

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

#include 
#include 
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.c gcc
icc/icpc –openmp hello_world.c intel (linux)
cc –openmp hello_world.c Cray
pgcc –mp hello_world.c pgi

2、如何规定线程数

有三种方法,下面是当初的截图,忘了翻译了… 或者问GPT也行。
学习笔记 —— C++并行库OpenMP_第1张图片

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

schedule description
Static (默认)Chunk-size固定,线程所执行的chunk固定
Dynamic Chunk-size固定,线程按需请求chunk执行
Guided Chunk-size逐渐降低,线程按需请求chunk执行

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

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

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

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

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

#include
#include
#include

#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 π的例子:
学习笔记 —— C++并行库OpenMP_第2张图片

相关理论在这:
学习笔记 —— C++并行库OpenMP_第3张图片

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

PC的CPU: AMD 5800H

学习笔记 —— C++并行库OpenMP_第4张图片
C++编译后的性能变化趋势如下:
学习笔记 —— C++并行库OpenMP_第5张图片
可以看到,C的结果与我们的预想基本一致,线程数越大运算越快;线程数大到一定程度速度就不怎么增加了。
而C++的结果却出乎意料,但仅就耗时的数量级来看,C++的性能是远高于C的。我暂时还不能解释原因…

你可能感兴趣的:(HPC,c++,学习,笔记)