【学习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(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 
#include 
#include 

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

你可能感兴趣的:(编译和调试,cmake,OpenMP,reduction)