炼数成金 门户 CUDA 查看内容

OpenMP多线程应用程序性能分析

2015-9-11 13:52| 发布者: 炼数成金_小数| 查看: 1658| 评论: 0|原作者: beck_zhou|来自: CSDN

摘要: OpenMP获得应用程序多线程并行化的能力不是凭空而来的,它需要一定程序库的支持,库中代码的运行必然会带来一定的开销。实际上并不是所有的代码都需要并行化,有些代码在并行化后执行的效率反而不如串行时高,原因就 ...

算法 基础 计算机

2.3.4 OpenMP多线程应用程序性能分析
影响性能的主要因素有
(1)OpenMP本身的开销
OpenMP获得应用程序多线程并行化的能力不是凭空而来的,它需要一定程序库的支持,库中代码的运行必然会带来一定的开销。实际上并不是所有的代码都需要并行化,有些代码在并行化后执行的效率反而不如串行时高,原因就是加上了并行化所带来的开销后,代码的执行效率降低。因此,只有在并行执行代码段负担足够大,而引入OpenMP本身的开销又足够小时,引入并行化操作才能提高程序执行效率。

(2)负载均衡
已知一个OpenMP应用程序在执行的过程中,有很多的同步点,线程只有在进行同步之后才能继续执行下面的代码。因此某一个线程在执行到同步点之后,若没有进一步的工作需要完成,此线程只有等待其它线程执行完毕后才能继续执行。此时,如果各个线程之间的负载不均衡,就有可能出现某些线程“空等”,而另外一些线程因负担沉重,要很长事件才能完成任务。看下面的例子:

示例程序见例2_5
程序运行结果为:
count=9350609
考虑负载均衡修改程序后的运行结果
count=5191944
上面程序中的QueryPerformanceCounter()函数用于获得CPU内部的计数器的值,在代码前后分别获得的计数器的值的差越大,说明这段代码执行的时间越长。该值和CPU的主频有关,在不同的计算机上,该值是没有可比性的。

可以看到,这两个循环的工作量是一样的,但是运行时间几乎差了一倍。由于使用了循环并行化,第一个循环OpenMP将前50个循环任务分配给0号线程,将后面50个循环任务分配给1号线程。前面50循环执行的是50个空操作,而后面的50个循环执行的负担沉重的任务,造成了负载不均衡,0号线程很快执行完毕,用很长的时间等待1号线程执行。在第二个循环中,OpenMP仍然将前面50个循环分配给0号线程,将后面50个循环分配给1号线程,,但是负载的分配发生了很大的变化,负载被均衡地分配到两个线程,两个线程几乎同时完成工作,这样可获得执行效率的提高。

(3)线程同步带来的开销
线程之间存在同步开销是多线程应用程序的特点,在进行同步时候必然会带来一定的开销。很多情况下,不合适的同步机制或算法会使代码的运行效率下降。
示例程序见例2_6
程序运行结果为:
sum=1000000, count=10548
sum=1000000, count=935416
程序的第一个循环是串行的,第二个循环是在第一个循环的基础上加上了并行化支持,为了消除数据竞争又加入了同步操作,由于对内存单元的操作是同步的,产生的实际运行过程是串行的,并且加上了并行化负担,使用运行效率比串行的效率还要低的多。

鲜花

握手

雷人

路过

鸡蛋

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

热门文章

     

    GMT+8, 2020-1-21 19:59 , Processed in 0.156453 second(s), 23 queries .