> 文章列表 > 【学习cmake-cookbook/chapter-03/recipe-05/cxx-example-3.5】

【学习cmake-cookbook/chapter-03/recipe-05/cxx-example-3.5】

【学习cmake-cookbook/chapter-03/recipe-05/cxx-example-3.5】

源码链接:cmake-cookbook/chapter-03/recipe-05/cxx-example-3.5 at master · qijitao/cmake-cookbook · GitHub

要想支持OpenMP,主要是在编译和链接时使用-fopenmp (下面代码中的OpenMP_CXX_FLAGS),为此需要检测OpenMP package,具体如下所示:

# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)# project name and language
project(recipe-05 LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(OpenMP REQUIRED)add_executable(example example.cpp)target_compile_options(examplePUBLIC${OpenMP_CXX_FLAGS})set_target_properties(examplePROPERTIESLINK_FLAGS ${OpenMP_CXX_FLAGS})message("OpenMP_CXX_FLAGS:${OpenMP_CXX_FLAGS}")

gcc中关于fopenmp的用法介绍:-fopenmp要激活 C/C++ 和 Fortran 的 OpenMP 扩展,必须指定编译时标志。详细参见:

https://gcc.gnu.org/onlinedocs/libgomp/Enabling-OpenMP.html

有关openMP的更详细使用,请参见官方的API定义:

        https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-2.pdf

被编译源码中通过#pragma omp 使用openmp特性,比如reduction:

#include <iostream>
#include <omp.h>
#include <string>int main(int argc, char *argv[]) {std::cout << "number of available processors: " << omp_get_num_procs()<< std::endl;std::cout << "number of threads: " << omp_get_max_threads() << std::endl;auto n = std::stol(argv[1]);std::cout << "we will form sum of numbers from 1 to " << n << std::endl;// start timerauto t0 = omp_get_wtime();auto s = 0LL;
#pragma omp parallel for reduction(+ : s)for (auto i = 1; i <= n; i++) {s += i;}// stop timerauto t1 = omp_get_wtime();std::cout << "sum: " << s << std::endl;std::cout << "elapsed wall clock time: " << t1 - t0 << " seconds" << std::endl;return 0;
}

 reduction的处理过程:参见https://blog.csdn.net/gengshenghong/article/details/7000685

#define COUNT 10int main(int argc, _TCHAR* argv[])  
{int sum = 100;		// Assign an initial value.
#pragma omp parallel for reduction(+:sum)for(int i = 0;i < COUNT; i++) {sum += i;sum = 1;}printf("Sum: %d\\n",sum);return 0;  
}

过程大概如下:
(1)sum=100初始值

(2)进入并行区域,创建4个线程的4个副本:sum0=sum1=sum2=sum3=0;

(3)计算完成后,得到sum0',sum1',sum2',sum3'

(4)计算sum,sum=sum op sum 0‘ op sum1’ op sum2‘ op sum3’。
 

有关OpenMP reduction的进一步说明和举例,请参见https://learn.microsoft.com/zh-cn/cpp/parallel/concrt/convert-an-openmp-loop-that-uses-a-reduction-variable?view=msvc-170