源码链接: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(example
PUBLIC
${OpenMP_CXX_FLAGS}
)
set_target_properties(example
PROPERTIES
LINK_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 timer
auto t0 = omp_get_wtime();
auto s = 0LL;
#pragma omp parallel for reduction(+ : s)
for (auto i = 1; i <= n; i++) {
s += i;
}
// stop timer
auto 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 10
int 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