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

 我来答
璐一洋溢
2017-04-29 · TA获得超过449个赞
知道小有建树答主
回答量:687
采纳率:0%
帮助的人:266万
展开全部
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本身的消耗。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式