关于单CPU.docVIP

  1. 1、本文档共3页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
关于单CPU

关于单CPU,多CPU上的原子操作 所谓原子操作,就是不可中断的一个或一系列操作 。 硬件级的原子操作: 在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是 原子操作,因为中断只能发生于指令之间。这也是某些CPU指令系统中引入了test_and_set、test_and_clear等指令用于临界资源互斥的原因。 在对称多处理器(Symmetric Multi-Processor)结构中就不同了,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。 在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀LOCK,经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的 原子性。 软件级的原子操作: 软件级的原子操作实现依赖于硬件原子操作的支持。 对于linux而言,内核提供了两组原子操作接口:一组是针对整数进行操作;另一组是针对单独的位进行操作。 2.1. 原子整数操作 针对整数的原子操作只能对atomic_t类型的数据处理。这里没有使用C语言的int类型,主要是因为: 1) 让原子函数只接受atomic_t类型操作数,可以确保原子操作只与这种特殊类型数据一起使用 2) 使用atomic_t类型确保编译器不对相应的值进行访问优化 3) 使用atomic_t类型可以屏蔽不同体系结构上的数据类型的差异。尽管Linux支持的所有机器上的整型数据都是32位,但是使用atomic_t的代码只能将该类型的数据当作24位来使用。这个限制完全是因为在SPARC体系结构上,原子操作的实现不同于其它体系结构:32位int类型的低8位嵌入了一个锁,因为SPARC体系结构对原子操作缺乏指令级的支持,所以只能利用该锁来避免对原子类型数据的并发访问。 原子整数操作最常见的用途就是实现计数器。原子整数操作列表在中定义。原子操作通常是内敛函数,往往通过内嵌汇编指令来实现。如果某个函数本来就是原子的,那么它往往会被定义成一个宏。 在编写内核时,操作也简单: atomic_t use_cnt; atomic_set(use_cnt, 2); atomic_add(4, use_cnt); atomic_inc(use_cnt); 2.2. 原子性与顺序性 原子性确保指令执行期间不被打断,要么全部执行,要么根本不执行。而顺序性确保即使两条或多条指令出现在独立的执行线程中,甚至独立的处理器上,它们本该执行的顺序依然要保持。 2.3. 原子位操作 原子位操作定义在文件中。令人感到奇怪的是位操作函数是对普通的内存地址进行操作的。原子位操作在多数情况下是对一个字长的内存访问,因而位号该位于0-31之间(在64位机器上是0-63之间),但是对位号的范围没有限制。 编写内核代码,只要把指向了你希望的数据的指针给操作函数,就可以进行位操作了: unsigned long word = 0; set_bit(0, word); /*第0位被设置*/ set_bit(1, word); /*第1位被设置*/ clear_bit(1, word); /*第1位被清空*/ change_bit(0, word); /*翻转第0位*/ 为什么关注原子操作? 1)在确认一个操作是原子的情况下,多线程环境里面,我们可以避免仅仅为保护这个操作在外围加上性能开销昂贵的锁。 2)借助于原子操作,我们可以实现互斥锁。 3)借助于互斥锁,我们可以把一些列操作变为原子操作。 GNU C中x++是原子操作吗? 答案不是。x++由3条指令完成。x++在单CPU下不是原子操作。 对应3条汇编指令 movl x, %eax addl $1, %eax movl %eax, x 在vc2005下对应 ++x; 004232FA mov eax,dword ptr [x] 004232FD add eax,1mov dword ptr [x],eax 仍然是3条指令。 所以++x,x++等都不是原子操作。因其步骤包括了从内存中取x值放入寄存器,加寄存器,把值写入内存三个指令。 如何实现x++的原子性? 在单处理器上,如果执行x++时,禁止多线程调度,就可以实现原子。因为单处理的多线程并发是伪并发。 在多处理器上,需要借助cpu提供的Lock功能。锁总线。读取内存值,修改,写回内存三步期间禁止别的CPU访问总线。同时我估计使用Lock指令锁总线的时候,OS也不会把当前线程调度走了。要是调走

文档评论(0)

xy88118 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档