openMP使用

本文通过实例探讨了OpenMP在多线程优化中的应用,包括如何利用section特性分配任务到不同线程,以及在实际运行过程中遇到的性能问题及其解决办法。

openMP使用

项目需要对程序的运行进行加速,在不考虑更换硬件的前提下,考虑采用多线程对代码进行优化,以下记录学习过程。

处理器采用大疆秒算2-C,CMakeList配置参考这篇博客:
在CMakelist.txt中配置OpenMP

openMP之section

#pragma omp parallel sections之后的大括号括起来的部分会使用多线程执行,每一个#pragma omp section括起来的部分会分配一个线程去执行,如果section数目多于CPU内核数,那么就会等有空余的内核时才会执行剩余的section,代码框架如下:

#pragma omp parallel sections
  {
    #pragma omp section 
    {
      ......
    }
    #pragma omp section
    {
      ......
    }
    ......
  }

测试代码

使用循环进行性能测试,其中整体代码外层循环执行1000000000次,对sum进行操作,代码如下:

int sum=0;

int main( ) {
	double t1, t2;
	t1 = omp_get_wtime();
	for(int i=0; i<1000000000; ++i) {
		for(int j=0; j<10; ++j) sum ++;
		for(int j=0; j<9; ++j) sum --;
	}
	t2 = omp_get_wtime();
	std::cout << " time1: " << t2-t1 << std::endl;
	std::cout << sum << std::endl;
	return 1;
}

多线程代码分8个线程执行循环(我的处理器是8核的),每个代码块的外层循环125000000次,分别对sum1sum2sum8进行操作,代码如下:

int sum1=0, sum2=0, sum3=0, sum4=0, sum5=0, sum6=0, sum7=0, sum8=0;

void Sum(int index, int &tmp) {
  for(int i=(index*125000000); i<((index+1)*125000000); ++i) {
    for(int j=0; j<10; ++j) tmp ++;
    for(int j=0; j<9; ++j) tmp --;
  }
}

int main( ) {
	double t1, t2;
	t1 = omp_get_wtime();
	#pragma omp parallel sections
	{
	  #pragma omp section 
	  {
	    Sum(0, sum1);
	  }
	  #pragma omp section
	  {
	    Sum(1, sum2);
	  }
	  #pragma omp section 
	  {
	    Sum(2, sum3);
	  }
	  #pragma omp section
	  {
	    Sum(3, sum4);
	  }
	  #pragma omp section 
	  {
	    Sum(4, sum5);
	  }
	  #pragma omp section
	  {
	    Sum(5, sum6);
	  }
	  #pragma omp section 
	  {
	    Sum(6, sum7);
	  }
	  #pragma omp section
	  {
	    Sum(7, sum8);
	  }
	}
	t2 = omp_get_wtime();
	std::cout << " time2: " << t2-t1 << std::endl;
	std::cout << sum1 << "  " << sum2 << "  " << sum3 << "  " << sum4 << "  " 
	          << sum5 << "  " << sum6 << "  " << sum7 << "  " << sum8 << "  "  << std::endl;
	
	return 1;
}

代码执行后输出为:
在这里插入图片描述发现使用了多线程反而运行时间增加了,在一篇帖子中看到是由于CPUcache的乒乓效应,原帖:
高人帮看一下,openMP并行了以后怎么反而慢了 .

修改代码为:

int sum1=0;
char space1[65]; 
int sum2=0;
char space2[65];
int sum3=0;
char space3[65];
int sum4=0;
char space4[65];
int sum5=0;
char space5[65];
int sum6=0;
char space6[65];
int sum7=0;
char space7[65];
int sum8=0;

代码执行后输出为:在这里插入图片描述

实际应用测试

在这里插入图片描述图中横轴为实验次数,纵轴为运行时间,蓝色线为不用多线程的,橙色线为使用多线程的,发现效果并不理想,有时运行时间能降低,但有时运行时间反而更高了,具体原因不详。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值