周伟明的专栏

多核的免费午餐已回来

用户操作
[即时聊天] [发私信] [加为好友]
周伟明
周伟明的公告
一书已上市, 欢迎大家提出意见!
最近评论
bingbing200x:对数据结构不是很精通,有个疑问想请教一相周老师:

在Queue_InsertTail 函数中

if ( pQueue->uTail == pQueue->uMaxCount - 1 )

这一句看不太懂,数组中最后一个元素一直没有使用?
还是有其它方面的原因?
bingbing200x:you are all right
lande1985:唉 怎么说呢

用哲学的思想在现在的各方面好像都是可以的 啊

思想么

但是 传统的就要去其糟粕 取其精华拉!!

呵呵

世界的是中国的

但是中国的不一定是世界的!!!

xblue3:老子其实是精英主义,并非推崇愚民的.

知之无知,
为而无为,
用则无用,
物物而不物于物.

要先"知"而后无知....
从混沌到稳定有序的状态(熵理论),从而不治而治....
不知何来混沌?
像石头一样,无知无觉的,再修养修炼,也不会得道明明德的.

laiqinyi@……
xblue3:"道家追求长生与稳定可靠性"---

胡扯,长生不老是道教的最求,道家和道教是有区别的.


"记得好像是南怀瑾曾经总结过中国社会的一个基本规律"---
外儒内法.法家思想统治.

中国是儒道不分家的,这个是南师的观点.

鄙人陋知,纠正几点,中国的哲学不错,呵呵!希望大家发扬光大...
文章分类
    收藏
      相册
      最近文章
      1、多核新观念-象使用内存一样使用CPU?
      2、多核编程中的任务随机竞争模式的概率分析
      3、OpenMP创建线程中的锁及原子操作性能比较
      4、多核编程中的任务分组竞争模式
      5、称球问题的测试解法
      90%程序员写不出无BUG的二分查找程序?
      C/C++代码检视实例
      多核编程中的负载平衡难题
      多核编程中的锁竞争难题
      微软过桥问题与测试人员素养
      接口关系稳定原理探索
      接口设计定理
      模块分解原理与三权分立
      模块分解原理的探索
      测试驱动需求分析
      筑一座坝治好中国的沙漠
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 无锁编程与分布式编程那个更适合多核CPU?收藏

      新一篇: 菜鸟、夫子、玫林凯与测试 | 旧一篇: 多核系统中三种典型锁竞争的加速比分析

       
      无锁编程与分布式编程那个更适合多核CPU
       
      前一篇文章多核系统中三种典型锁竞争的加速比分析讲过了三种典型锁竞争情况下的加速比情况,特别是分布式锁竞争的加速比和CPU核数成正比,有很好的加速比性能。由于近些年在学术界中,无锁编程属于研究热点。那么使用无锁编程是不是可以取得更好的加速比性能呢?或者说无锁编程是不是更适合多核CPU系统呢?
      无锁编程主要是使用原子操作替代锁来实现对共享资源的访问保护,举个例子,要对某个整数变量进行加1操作的话,用锁保护操作的代码如下:
      int a = 0;
      Lock();
      a+= 1;
      Unlock();
       
      如果对上述代码反编译可以发现 a+=1;被翻译成了以下三条汇编指令:
      mov         eax,dword ptr [a]
      add         eax,1
      mov         dword ptr [a],eax
       
       
      如果在单核系统中,由于在上述三条指令的任何一条执行完后都可能发生任务切换,比如执行完第1条指令后就发生了任务切换,这时如果有其他任务来对a进行操作的话,当任务切换回来后,将继续对a进行操作,很可能出现不可预测的结果,因此上述三条指令必须使用锁来保护,以使这段时间内其他任务无法对a进行操作。
      需要注意的是,在多核系统中,因为多个CPU核在物理上是并行的,可能发生同时写的现象;所以必须保证一个CPU核在对共享内存进行写操作时,其他CPU核不能写这块内存。因此在多核系统中和单核有区别,即使只有一条指令,也需要要加锁保护。
      如果使用原子操作来实现上述加1操作的话,例如使用VC里的InterlockedIncrement来操作的话,那么对a的加1操作需要以下语句
      InterlockedIncrement (&a);
      这条语句最终的实际加1操作会被翻译成以下一条带lock前缀的汇编指令:
      lock xadd   dword ptr [ecx],eax
       
      使用原子操作时,在进行实际的写操作时,使用了lock指令,这样就可以阻止其他任务写这块内存,避免出现数据竞争现象。原子操作速度比锁快,一般要快一倍以上。
      使用lock前缀的指令实际上在系统中是使用了内存栅障(memory barrier),当原子操作在进行时,其他任务都不能对内存操作,会影响其他任务的执行。因此这种原子操作实际上属于一种激烈竞争的锁,不过由于它的操作时间很快,因此可以看成是一种极细粒度锁。
      在无锁(Lock-free)编程环境中,主要使用的原子操作为CAS(Compare and Swap)操作,在VC里对应的操作为InterlockedCompareExchange或者InterlockedCompareExchangeAcquire如果是64位的操作,需要使用InterlockedCompareExchange64或者InterlockedCompareExchangeAcquire64。使用这种原子操作替代锁的最大的一个好处是它是非阻塞的。
      按照微软MSDN的说明,InterlockedCompareExchange带有全局的内存栅障(full memory barrier),在使用了full memory barrier的情况下,即使不是访问同一内存变量的原子操作也会发生竞争,从竞争形式上来讲,会发生固定式锁竞争或随机锁竞争现象,并且无法实现分布式锁竞争的竞争模式,比起使用普通锁的竞争会更激烈,因此最终得到的加速比会比上一篇文章里讲的固定式锁竞争还要糟糕。
      对于象InterlockedCompareExchangeAcquire这类的原子操作,没有使用full memory barrier,因此性能理论上会比使用full memory barrier的原子操作好很多(由于目前这类原子操作只有在特定的机器才支持,具体性能到底如何没有测试过,微软的MSDN里也对性能方面作出说明)。但是如果采用固定式锁竞争形式,其加速比仍然是按照前面的固定式锁竞争的加速比公式来计算:

      由于原子操作速度比锁快,其实相比于普通锁操作,相当于加锁解锁时间 1减少了2~3倍左右,不妨以2倍来计算,对应的任务粒度会增大一倍,为 ,另外由于原子操作内的锁内计算通常只是简单一两条指令,因此其锁粒度很小,可以近似看成为0,因此加速比为:

      因此在固定式锁竞争情况下,加速比的极限值约等于使用普通锁时的2倍任务粒度大小,大约比使用 普通锁时的加速比大一倍左右。加速比并不能随CPU核数增长而线性增加。
      对于随机式锁竞争情况,加速比为:
      如果讲普通锁操作改成原子操作,将锁粒度近似看成0,那么 ,对于任务粒度非常大的情况,概率p的增加并不大;对于任务粒度非常小的情况,概率p最大可以增大近似一倍,加速比相比于普通锁也可以获得一定程度的提高。
      对于普通锁随机竞争情况下的最坏情况,加速比为:
      改成原子操作后,加速比为:
      只是相对于普通锁竞争情况提高了一些,并不能随CPU核数增加而增加。
      注意上面没有考虑无锁编程的算法开销,采用无锁编程时,要完成一个CAS操作需要在一个循环里来完成,有可能要循环很多次才能完成一次写操作,因此实际性能并达不到上面的计算结果。
      因此即使使用无锁编程,如果锁竞争形式仍然是固定式竞争或随机竞争的形式,加速比性能仍然是不乐观的,仍然跟分布式锁竞争的加速比差很远,因为分布式锁竞争在最坏情况下加速比也可以做到接近CPU核数。
      当然有人也会提出,既然分布式锁竞争的加速比性能这么好,那么将原子操作替代普通锁来进行分布式竞争,岂不是可以取得更好的加速比性能?理论上来说,如果以不带full memory barrier原子操作来替代普通锁进行分布式竞争,是可以取得比普通锁进行分布式竞争更好的加速比,分布式加速比为 ,使用原子操作后,任务粒度将会增大2~3倍,对于任务粒度非常小的情况,比如任务粒度小于0.5(这种情况实际中很难出现),加速比将比使用普通锁时增大一倍左右,对于任务粒度较大的情况,加速比增加并不明显。
      对于任务粒度的大小,很大程度上取决于程序员对任务的划分,只要程序员在划分任务时不要将任务粒度划得太小,这样就可以降低任务粒度对加速比造成的影响。
      但是使用分布式锁竞争时,性能已经可以和单核多任务时的程序性能接近了,使用无锁编程难度非常高,程序复杂度也非常高,非专业人士难以掌握,普通程序员想要进行无锁编程几乎是不可能的事情。而分布式编程的难度和以前单核多任务时代的数据结构算法编程难度差不多,普通程序员都可以掌握。因此在实际情况中只要任务粒度不是太小,就没有必要过于追求性能,使用普通锁的分布式锁竞争已经足够了。
      从目前无锁编程的发展来看,已经实现了的无锁算法很有限,并且功能也很有限,并且无锁编程是独立于以前的单核时代的编程的,使用无锁编程几乎无法复用以前的成果。分布式编程是在原有的单核多任务编程基础上发展而来,可以继承以前单核时代的成果,比如队列池便可以继承已有的队列算法,因此采用分布式编程可以大大减轻将现有单核程序移植到多核系统中的工作量,只要对现有程序进行一些重构即可完全支持多核CPU系统。
      综上所述,可以得到下表所示的结论
       
      比较项目
      无锁编程
      分布式编程
      1
      加速比性能
      取决于竞争方式,除非也采用分布式竞争,否则不如分布式锁竞争的性能
      加速比和CPU核数成正比关系,接近于单核多任务时的性能
      2
      实现的功能
      有限
      不受限制
      3
      程序员掌握难易程度
      难度太高,过于复杂,普通程序员无法掌握,目前世界上只有少数几个人掌握。
      和单核时代的数据结构算法难度差不多,普通程序员可以掌握
      4
      现有软件的移植
      使用无锁算法后,以往的算法需要废弃掉,无法复用
      可以继承已有的算法,在已有程序基础上重构即可。
       
      从上表的四个方面的综合比较可以看出,无锁编程的实用价值是远远不如分布式编程的,因此分布式编程比无锁编程更适合多核CPU系统。                                    
       
       

      发表于 @ 2007年09月27日 18:31:00|评论(loading...)|收藏

      新一篇: 菜鸟、夫子、玫林凯与测试 | 旧一篇: 多核系统中三种典型锁竞争的加速比分析

      评论

      #gazel 发表于2007-12-14 13:01:09  IP: 202.101.8.*
      晕, 刚刚看前面, 就看到了一堆错误 - 你也太误导人了吧
      1. 拿任务切换而不是多processor来解释锁的作用, 你也想得出来?

      2. 使用lock前缀的指令实际上在系统中是使用了内存栅障(memory barrier)" - 你懂什么是memory barrier么?
      #drzhouweiming 发表于2007-12-14 14:25:10  IP: 58.31.70.*
      To gazel:

      多谢指出问题,文章开头关于为什么要加锁的问题确实没有讲透彻,有遗漏。
      现在修改了一下,加上了多核方面的加锁保护说明,不知道说得对不对?请看看还有没有什么问题。

      关于memory barrier,由于我对硬件没有研究,确实不是十份了解,有一次听Intel的人讲原子操作时,说会锁住内存,
      即使用了memory barrier,只有一个任务在执行内存操作,其他任务都不能进行内存操作,不知道对不对,如果有错请指正。
      #gazel 发表于2007-12-14 17:29:36  IP: 202.101.8.*
      您这么谦虚我还真不好意思呢, 不过你的原文确实错漏百出. :)

      先说一下memory barrier吧 - memory barrier的意思是禁止memory操作跨过这个barrier. 这个概念常用于编译系统和体系结构中:
      1. 编译器中: 为了优化代码, 编译器在认为安全的时候(也就是不影响语义的情况下)经常会调整指令的顺序(所谓的指令调度 - instruction schedule). 可是编译器是不知道多线程的(假设多线程不是编程语言的一部分) - 有时候这对memory指令的调度就会改变程序的语义, 这是程序员所不期望看到的, 这个时候他可以选择使用memory barrier (一般来说是个编译器的intrinsic), 编译器就不会式指令调度跨国memory barrier.
      2. 体系结构中: 现在的CPU一般也会做指令调度, 也会出现和编译器相同的问题. 为了解决这个问题, CPU介绍某些指令来做memory barrier. 具体到lock xxx 指令, lock xxx是memory barrier, 这是其副作用, 但其设计的目的和memory barrier无关. 它的语义是锁住内存总线知道该指令完成.

      barrier会扩展出很多用法: 是否允许后面的memory操作向前调度, 是否允许前面memory向后, 只对store, 只对load, 等等 - 不过基本概念就是这样了.
      #drzhouweiming 发表于2007-12-15 08:35:39  IP: 58.31.70.*
      To gazel:
      你说的这些内容好像在有些书里面讲过(由于我的书前几天都打包托运了,所以无法确定是那些书),在云风的博客里也有文章讲Intel的fence指令,
      谈到了SFENCE和LFENCE指令及乱序执行等问题,不过我感觉好像都是在谈单核系统中的问题。

      多核机器属于MIMD(多指令流多数据流),同时有多个指令流在并行执行,memory barrier在多核系统中应该主要是为了防止多个指令流同时操作同一数据流吧。不知道我理解得对不对,有错请指正。

      不过对于程序员来说,这些并不是很重要,程序员只要知道那些地方会出现数据竞争问题,使用锁操作或原子操作来避免数据竞争就够了。
      #domemy 发表于2008-10-08 11:52:56  IP: 61.173.3.*
      Linux 环境下的多核调试
      — Intel + Totalview 强强联合!
      目前,在软件开发行业,各种性能优异的调试工具层出不穷。但是,它们中的绝大部分都只支持windows环境。即使能支持linux平台,操作起来也很不方便。因此,对于长期在linux上编写程序的开发人员来说,如何调试就成了一个令人头痛的问题!Intel软件 和 Totalview Debugger 正是在这种情况下应运而生!
      Intel软件可以在英特尔架构上产生出色的应用程序性能,并可以利用最新英特尔多核处理器的各项先进功能。TotalView Debugger与Intel软件的结合将会掀起一场linux下调试工具的革命!
      TotalView Debugger是一个linux平台并行环境下的调试工具,它的IDE环境、多线程(进程)调试能力、内存调试能力、集群调试能力在业界都是无与伦比的!
      XLsoft携手Intel、TotalView公司于2008年10月30日在上海举行“Linux 环境下的多核调试”免费培训讲座。我们非常荣幸地邀请您参加,并提供免费软件试用光盘!

      一、报名方式
      在线注册页面:
      [url=http://www.xlsoft.com.cn/TotalView/TotalView_download.asphttp://www.xlsoft.com.cn/TotalView/TotalView_download.asp][/url]
      报名热线:021-62128912/010-84492749
      报名Email:Marketing@xlsoft.com.cn

      二、讲座内容:
      1. Linux 平台下程序调试工具概述
      2. Intel 软件功能介绍
      3. Totalview Debugger功能介绍

      三、讲座时间:
      2008年10月30日(星期四)14:00 ~ 17:00

      四、讲座地点:
      上海青松城大酒店3楼长悦厅
      (徐家汇肇家浜路777号东安路口,距衡山路站约15分钟路程)

      四、活动详情:
      联系人:王娟
      Tel:021-62128916 Mobile: 15000262606
      E-mail:kiko.wang@xlsoft.com.cn

      咨询热线:
      021-62128912 010-84492749
      更多的服务信息,请联系我们Marketing@xlsoft.com.cn or 联系方式。

      上海世全软件信息技术有限公司
      联系电话 上海:021-62128912 北京:010-84492749
      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © 周伟明