永发信息网

为什么用OpenMP并行计算会出现比单线程还要慢

答案:1  悬赏:50  手机版
解决时间 2021-03-25 07:56
  • 提问者网友:棒棒糖
  • 2021-03-24 22:15
为什么用OpenMP并行计算会出现比单线程还要慢
最佳答案
  • 五星知识达人网友:玩世
  • 2021-03-24 23:46
openmp默认使用的schedule是取决于编译器实现的。gcc默认使用schedule(dynamic,1),也就是动态调度并且块大小是1。在你的程序里面,这种调度是及其低效的,看代码都能预期到,不太可能比单线程快。
动态调度的一种简单理解方式是,计算任务存在一个任务队列里面,你的for循环每一个i值对应一个计算任务。每个线程每次提取一批任务,然后计算。“一批”是多少呢?就是前面说的块大小,在你的程序里面是1。提取任务需要什么操作呢?因为这个任务队列是多线程共享的,提取任务前必须加锁,读取一批,从队列中移除,然后解锁。说到这里,你应该已经知道原因了。
你的线程一次只提取一次计算任务,这个任务还完成得很快。然后所有的16个线程排着队,逐个去加锁,抢任务,然后解锁让其它线程继续抢。然后马上发现这个任务很快,又要重新去排队等任务,始终处于饥饿状态。注意排队的时候可能也是要占cpu的,因为使用了busy wait,所以可能你看来十六核满负荷,但是其实啥也没干。
我的建议就是,使用static schedule,或者增加dynamic schedule的块大小,比如1024,取决于你循环多少次。一般如果你知道每次循环的执行时间基本都是一样,并且是专用服务器设置好affinity,无其它负荷无oversubscription无numa问题的话,static schedule会是个比较好的选择。这样每个线程做哪些任务只需要进行一次分配,最小化了openmp本身的消耗。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯