并行优化:OpenMP

OpenMP是一种用于共享内存系统的多线程程序设计方案,支持C,C++,Fortran编程语言。OpenMP提供了对并行算法的高层抽象,特别适合多核计算机上道德并行编程设计。当前很多编译器都内置了OpenMP,当编译器不支持OpenMP时,编译器会忽视OpenMP指令,程序自动退化为串行程序,不影响程序的正常编译。特别需要强调一点:在VS编译器中,只有在Release模式下才能体现OpenMP并行化,Debug模式下编译器不会对代码进行优化。

OpenMP采用fork-join(分叉-合并)并行执行模式。线程遇到并行结构时,就会创建由其自身及其它一些线程组成的线程组。遇到并行结构的线程称为线程组中的主线程,其它线程称为组的从线程。所有线程组的成员都执行并行构造内的代码。如果某个线程完成了其在并行构造内的工作,它会在并行构造末尾的隐式屏蔽处等待。当所有组成员都达到该屏蔽处,这些线程就可以离开该屏障。主线程继续执行并行结构之后的代码,而从线程则等待被召集加入到其他组。

OpenMP运行时库维护一个线程池,该线程池的线程可以用作并行区域中的从线程。当线程遇到并行结构并需要创建包含多个线程的线程组时,该线程将检查该池,从池中获取空闲线程,将其作为组的从线程。如何池中没有足够的空闲线程,则主线程获取的从线程可能会比所需的要少。组完成执行并行区域时,从线程就会返回到池中。
————————————————
原文链接:https://blog.csdn.net/qq_30024069/article/details/93355022

CMakeLists.txt 设置

cmake_minimum_required(VERSION 2.10)
project(TEST)

set(TEST_VERSION 0.1)

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)

FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS"${CMAKE_EXE_LINKER_FLAGS}${OpenMP_EXE_LINKER_FLAGS}")
endif()

aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRC)

include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)

add_executable(main ${DIR_SRC})
target_link_libraries(main libamd.a)

示例代码

并行优化:OpenMP_第1张图片

for 循环

#include
#include
#include

using namespace std;
 
int main(){
	int n = 100;
	#pragma omp parallel 
	#pragma omp for
	for (int i = 1; i < n; i++)	{
		cout <<this_thread::get_id()<<"\t"<< i << endl;
	}
	system("pause");
	return 0;
}

注意:一定要在#pragma omp for指令前加入#pragma omp parallel指令,不然退化为串行执行

sections构造

sections构造用于封装要在线程组中分配的一组结构化代码块,每个代码块由线程组内的一个线程执行一次。每段以section指令开头,该指令对第一段为可选指令。

#pragma omp parallel
#pragma omp sections
{
	#pragma omp section  //此处可选字段,可以不加
	cout << "work1" << endl;
 
	#pragma omp section  //此处必选字段,不加此字段报错OpenMP“sections”区域中的结构化块的前面必须是“#pragma omp section”	
	cout << "work2" << endl;
 
	#pragma omp section  //此处必选字段
	cout << "work3" << endl;
}

输出:work1,work2,work3(顺序不一定,但是只执行一次)

你可能感兴趣的:(C++,c++,OpenMP,并行)