[转贴]多核编程中的锁竞争现象

赖勇浩 2007-04-12 10:20:48

注:本文全文转贴自drzhouweiming的专栏(http://blog.csdn.net/drzhouweiming),本文有一幅插图,大家可以在这里查看原文:http://blog.csdn.net/drzhouweiming/archive/2007/04/10/1559718.aspx




多核编程中的锁竞争现象

在前一篇讲解多核编程的几个难题及其对策(难题一)的文章中提到了锁竞争会让串行化随CPU的核数增多而加剧的现象,这篇文章就来对多核编程的锁竞争进行深入的分析。
为了简化起见,我们先看一个简单的情况,假设有4个对等的任务同时启动运行,假设每个任务刚开始时有一个需要锁保护的操作,耗时为1,每个任务其他部分的耗时为25。这几个任务启动运行后的运行情况如下图所示:

图1:对等任务的锁竞争示意图
在上图中,可以看出第1个任务直接执行到结束,中间没有等待,第2个任务等待了1个时间单位,第3个任务等待了2个时间单位,第3个任务等待了3个时间单位。
这样有3个CPU总计等待了6个时间单位,如果这几个任务是采用OpenMP里的所有任务都在同一点上进行等待到全部任务执行完再向下执行时,那么总的运行时间将和第四个任务一样为29个时间单位,加速系数为:(1+4×25)/ 29 = 3.48
即使以4个任务的平均时间27.5来进行计算,加速系数=101/27.5 = 3.67
按照阿姆尔达定律来计算加速系数的话,上述应用中,串行时间为1,并行处理的总时间转化为串行后为100个时间单位,如果放在4核CPU上运行的话,加速系数=p / (1 + (p-1)*f) = 4/(1+(4-1)*1/101) = 404/104 = 3.88
这就产生了一个奇怪的问题,使用了锁之后,加速系数连阿姆尔达定律计算出来的加速系数都不如,更别说用Gustafson定律计算的加速系数了。

其实可以将上面4个任务的锁竞争情况推广到更一般的情况,假设有锁保护的串行化时间为1,可并行化部分在单核CPU上的运行时间为t,CPU核数为p,那么在p个对成任务同时运行情况下,锁竞争导致的总等待时间为:1+2+…+p = p*(p-1)/2
耗时最多的一个任务所用时间为: (p-1) + t/p
使用耗时最多的一个任务所用时间来当作并行运行时间的话,加速系数如下
S(p) = t / (p-1 + t/p) = p*t / (p*(p-1)+t) (锁竞争下的加速系数公式)
这个公式表明在有锁竞争情况下,如果核数固定情况下,可并行化部分越大,那么加速系数将越大。在并行化时间固定的情况下,如果CPU核数越多,那么加速系数将越小。
还是计算几个实际的例子来说明上面公式的效果:
令t=100, p=4, 加速系数=4×100 / (4*(4-1)+100) = 3.57
令t=100, p=16, 加速系数=16×100 / (16*(16-1)+100) = 4.7
令t=100, p=64, 加速系数=64×100 / (64*(64-1)+100) = 1.54
令t=100, p=128, 加速系数=128×100 / (128*(128-1)+100) = 0.78
从以上计算可以看出,当核数多到一定的时候,加速系数不仅不增加反而下降,核数增加到128时,加速系数只有0.78,还不如在单核CPU上运行的速度。
上面的例子中,锁保护导致的串行代码是在任务启动时调用的,其实对等任务中在其他地方调用的锁保护的串行代码也是一样的。
对等型任务的锁竞争现象在实际情况中是很常见的,比如服务器软件,通常各个客户端处理任务都是对等的,如果在里面使用了锁的话,那么很容易造成上面说的加速系数随CPU核数增多而下降的现象。
以前的服务器软件一般运行在双CPU或四CPU机器上,所以锁竞争导致的加速系数下降现象不明显,进入多核时代后,随着CPU核数的增多,这个问题将变得很严重,所以多核时代对程序设计提出了新的挑战。以前的多任务下的编程思想放到多核编程上不一定行得通。
所以简单地认为多核编程和以前的多任务编程或并行计算等同的话是不切实际的,在讲串行化难题的那篇文章中提出了一些解决方面的对策,但是那些对策还有待业界继续努力才能做得到。
当然由于目前市面上销售的多核CPU还是双核和四核的,等到16核以上的CPU大规模进入市场可能还有几年时间,相信业界在未来的几年内能够对于上面对等任务上的锁竞争问题找到更好的解决方案。

作者介绍:周伟明,自由职业,从事软件行业十年有余。目前主要关注软件测试、多核编程、软件设计等基础方面的内容。写有《多任务下的数据结构与算法》一书,目前正在写作《软件测试实践》一书,计划在不久的将来写一本多核编程方面的书籍。
...全文
2482 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
chmdcr 2008-02-26
  • 打赏
  • 举报
回复
mark
sjjf 2007-04-23
  • 打赏
  • 举报
回复
mark
dxcnjupt 2007-04-20
  • 打赏
  • 举报
回复
补充一点,对于只读文件,可以不用上锁。
dxcnjupt 2007-04-20
  • 打赏
  • 举报
回复
不知道楼主的书卖的怎么样,我也想去出书。

任务时间=管理时间+运算时间
加速率=原计算时间/(任务时间×核数)
其中原计算时间是固定不变的。

管理时间越大,加速率越小。
当管理时间>运算时间时,加速率小于1。这时,每个任务等待解锁的时间,大于运算时间。

作者说的 锁竞争导致的加速系数下降 的问题,实际上根本就不存在。服务器端处理一个文件片耗时10000单位(以加锁耗时为一个单位)以上,相对来说管理开销非常之小。 而且服务器上有着众多的文件,以及单文件上的不同片;多个服务端同时读一个文件同一个文件片的可能性非常之小。
linuxhaha 2007-04-19
  • 打赏
  • 举报
回复
它说的是“自旋锁”。
wshong 2007-04-17
  • 打赏
  • 举报
回复
顶!!!!
tongshou 2007-04-13
  • 打赏
  • 举报
回复

不好意思,上面数据(t=10000) 输入错误,更正如下:

这些数据不能用于说明 多核本身的问题,问题出在 时间t=100的数太小了, 如果取t=10000
看看结果会怎样:
令t=10000, p=4, 加速系数=3.995
令t=10000, p=16, 加速系数=15.625
令t=10000, p=64, 加速系数=41.984
令t=10000, p=128, 加速系数=48.751
tongshou 2007-04-13
  • 打赏
  • 举报
回复

1) 多核下需要锁 才能并行处理数据。难道单核下就可以不需要 锁而省下一些时间码?

2)
令t=100, p=4, 加速系数=4×100 / (4*(4-1)+100) = 3.57
令t=100, p=16, 加速系数=16×100 / (16*(16-1)+100) = 4.7
令t=100, p=64, 加速系数=64×100 / (64*(64-1)+100) = 1.54
令t=100, p=128, 加速系数=128×100 / (128*(128-1)+100) = 0.78

这些数据不能用于说明 多核本身的问题,问题出在 时间t=100的数太小了, 如果取t=10000
看看结果会怎样:
令t=100, p=4, 加速系数=3.995
令t=100, p=16, 加速系数=15.625
令t=100, p=64, 加速系数=41.984
令t=100, p=128, 加速系数=48.751

这里 128核 却显示巨大效率!因此,这里能说明的是:

如果串行处理数据的时间不长,改用多核并行处理,并不见得会明显缩短处理时间,甚至可能会增加时间!如果串行处理数据的时间不是很长,没有必要太多核去并行处理,因为效率并不是线性地提高效率,对应不同串行处理数据的时间,会有一个比较理想的核数。

3)无论如何,这里不能因为一处(情形)并行处理数据效率欠佳 而整个否定 多核的效率价值,事实上多核还 可以并行处理很多不直接相关、不需要锁保护的数据。

4)也许我对“锁”的理解与 作者的不同?这里的“锁”是指多线程编程中的“锁”,还是指多核内部运行过程需要协调而用的什么特殊“锁”(这方面我 不懂^_^)?































568

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧