栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

随手记录 OpenMP/omp C++ 下 for 并行 多线程加速

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

随手记录 OpenMP/omp C++ 下 for 并行 多线程加速

前言

一直觉得gpir [高斯过程下的路径规划问题] 这一波,CJ哥的代码学下来的知识真的是太多了,上一篇是有关此的是:【路径规划】OSQP曲线平滑 公式及代码

这一篇主要记录omp库的使用,如何加速C++的整体代码运行的,特别是在有大量for循环下的对比,因为看到gird_map那边多用这个库进行for的并行

python的实现应该是走multiprocess这个库,或者是ray,这一点曾经在这篇博文中写过

GPIR源码地址:https://github.com/jchengai/gpir

从上面摘取示例:

  omp_set_num_threads(4);
  {
#pragma omp parallel for
    // column scan
    for (int x = 0; x < dim[0]; ++x) {
      g[x][0] = is_occupied(x, 0) ? 0 : inf;


      for (int y = 1; y < dim[1]; ++y) {
        g[x][y] = is_occupied(x, y) ? 0 : 1 + g[x][y - 1];
      }


      for (int y = dim[1] - 2; y >= 0; --y) {
        if (g[x][y + 1] < g[x][y]) g[x][y] = 1 + g[x][y + 1];
      }
    }
  }

相关深入可参考链接:https://www.cnblogs.com/mtcnn/p/9411892.html

官方OpenMP地址:https://www.openmp.org/spec-html/5.0/openmp.html

测试

ubuntu下需要安装一下

sudo apt install -y libomp-dev 

CMakeLists.txt配置

cmake_minimum_required(VERSION 3.13.0)
project(common CXX)

set(CMAKE_CXX_STANDARD 14)

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()

add_executable(omp_example src/omp_test/omp_example.cpp)

cpp文件:来源于参考链接处

#include 
#include "omp.h"

using namespace std;

void test()
{
	for (int i = 0; i < 80000; i++)
	{
	}
}

int main(int argc, char const* argv[]) 
{
	float startTime = omp_get_wtime();

	//指定2个线程
#pragma omp parallel for num_threads(2)
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
	float endTime = omp_get_wtime();
	printf("指定 2 个线程,执行时间: %fn", endTime - startTime);
	startTime = endTime;

	//指定4个线程
#pragma omp parallel for num_threads(4)
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
	endTime = omp_get_wtime();
	printf("指定 4 个线程,执行时间: %fn", endTime - startTime);
	startTime = endTime;

	//指定8个线程
#pragma omp parallel for num_threads(8)
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
	endTime = omp_get_wtime();
	printf("指定 8 个线程,执行时间: %fn", endTime - startTime);
	startTime = endTime;

	//指定12个线程
#pragma omp parallel for num_threads(12)
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
	endTime = omp_get_wtime();
	printf("指定 12 个线程,执行时间: %fn", endTime - startTime);
	startTime = endTime;

	//不使用OpenMP
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
	endTime = omp_get_wtime();
	printf("不使用OpenMP多线程,执行时间: %fn", endTime - startTime);
	startTime = endTime;
	return 0;
}

编译测试截图:【注意我测试的主机没有12个线程所以emm就8个】

当时做ray的时候,看到文档中曾说过 如果任务分给每个线程的时间和线程执行的时间差不多,可能越多线程反而速度也会慢下来,这时候主要瓶颈就在分配上了

所以在使用时 只需要前面加上库名,和每个for下指定线程数

#include "omp.h"

  omp_set_num_threads(4);
  {
#pragma omp parallel for
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
  }
          
// ============= OR ==========
#pragma omp parallel for num_threads(4)
	for (int i = 0; i < 80000; i++)
	{
		test();
	}
相关问题补充 pragma omp parallel for 与pragma omp parallel区别

问题来源:https://stackoverflow.com/questions/38080818/pragma-omp-parallel-for-vs-pragma-omp-parallel

解答如下,从原链接中英文参考而来

#pragma omp parallel
for(int i=0; i
   ...
}

这样做,是创建了并行块,for会被运行设置线程的个数次;所以 如下图所示运行,线程数设为4,N=4,那么会输出16次,也就是说这个for被运行了4次

---
#pragma omp parallel for
for(int i=0; i
   ...
}

这样做则是这个for被拆分成线程数,然后并行运行,所以只输出了一个for的文字,具体可见上一部分的时间对比

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917034.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号