一直觉得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 <iostream>
#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 个线程,执行时间: %f\n", 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 个线程,执行时间: %f\n", 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 个线程,执行时间: %f\n", 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 个线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
//不使用OpenMP
for (int i = 0; i < 80000; i++)
test();
endTime = omp_get_wtime();
printf("不使用OpenMP多线程,执行时间: %f\n", 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();
操作vector
其实和上面差不多,不过想来正好补充一下,顺便说一下,因为ax曾经做一下并行计算的东西,他说如果这个线程要用上一个线程的结果的话,在一些计算量大的情况下会造成堵塞。所以设置for的时候一定要检查一下,比如上面所说的grid map的并行操作的for就是专门设计了for循环以便能达到并行的效果的。更多可见此链接:【基础计算】ESDF栅格距离图计算并行加速版
#include <iostream>
#include "omp.h"
#include <vector>
using namespace std;
void test()
for (int i = 0; i < 16000000; i++)
int main(int argc, char const* argv[])
float startTime = omp_get_wtime();
int num=0;
vector<int> array_num;
int numP=2;
omp_set_num_threads(numP);
#pragma omp parallel for
for (int i = 0; i < 800; i++)
test();
num++;
array_num.push_back(num);
float endTime = omp_get_wtime();
printf("指定 %d 个线程,执行时间: %f\n", numP, endTime - startTime);
相关问题补充
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<N; i++) {
这样做,是创建了并行块,for会被运行设置线程的个数次;所以 如下图所示运行,线程数设为4,N=4,那么会输出16次,也就是说这个for被运行了4次
#pragma omp parallel for
for(int i=0; i<N; i++) {
这样做则是这个for被拆分成线程数,然后并行运行,所以只输出了一个for的文字,具体可见上一部分的时间对比