cpu_relax( )-----对自选循环等待(spin-wait loops)操作的优化【转】
cpu_relax()-----对自选循环等待(spin-wait loops)操作的优化
转自:http://www.doc100.net/bugs/t/173547/index.html
在lock_timer_base()函数中看到在for循环操作中调用了cpu_relax(),本来以为是要让出CPU,调度其他进程运行,但是看代码之后发现完全不是这么回事。cpu_relax()中只有一条调用语句,调用的是rep_nop函数。rep_nop()函数如下:
static inline void rep_nop(void)
{
asm volatile("rep; nop" ::: "memory");
}
只有一条简单的汇编语句,原来在论坛里看到过这条汇编语句,不是重复执行nop指令,"rep; nop"指令会被翻译成pause指令,到底是不是这样呢?反汇编一下看看,c代码如下:
#include <stdio.h> static inline void rep_nop(void)
{
asm volatile("rep; nop" ::: "memory");
} int main(void)
{
rep_nop();
return 0;
}
文件名保存在nop.c,使用gcc编译成目标文件nop.o,命令如下:
gcc -c nop.c
使用objdump来反汇编,命令如下:
objdump -s -d nop.o
反汇编的结果如下图所示:
从图中可以看出"rep; nop"指令被翻译成pause指令,因此实际上rep_nop()函数执行了一次pause指令。关于这条指令,intel的指令手册《Instruction Set Reference, M-Z》中讲的比较详细,这里总结一下。
pause指令的作用是:
1)提升spin-wait loops(自旋循环等待)的性能。在执行一个 spin-wait loops时,Pentium4处理会遇到严重的性能损失,因为在循环退出时,处理器会检测到一个可能的内存顺序冲突。pause指令会向处理器提供一种提示,告诉处理器当前所执行的代码序列是一个spin-wait loop操作。大多数情况下,处理器会根据这个提示避开内存序列冲突,从而提高处理器的性能。正是基于此,建议在spin-wait loop中使用pause指令。
2)pause指令的另外一个功能是让Pentium4处理器在执行spin-wait loop时可以减少电源的消耗。在等待资源而执行自旋等待时,Pentium4处理器以极快的速度执行自旋等待操作时,将会消耗很多电能,但使用pause指令则可以极大地减少处理器的电源消耗。
PAUSE 指令在 Pentium4 处理器中引入,但它也是向前兼容的。在早先的 IA-32 处理器里,PAUSE 指令实际上就相当于 NOP 指令。Pentium4 处理器以一种 预延迟(pre-defined delay)的技术来实现 PAUSE 指令。这种延迟也是有限度的,并且在一些处理器上是零延迟。该指令不会改变处理器的处理器的状态。
上面还提到一个概念就是内存顺序冲突(Memory order violation)。内存顺序冲突一般是由假共享引起,假共享是指多个CPU同时修改同一个缓存行的不同部分而引起的一个CPU的操作无效,当出现这个内存顺序冲突时,CPU必须清空流水线。
参考资料:
聊聊并发(五)——原子操作的实现原理
http://www.groad.net/bbs/read.php?tid-3373.html
cpu_relax( )-----对自选循环等待(spin-wait loops)操作的优化【转】的更多相关文章
- java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化
异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...
- 采用CAS算法 实现高性能的Disruptor 完成多线程下并发、等待、先后等操作
来源:https://blog.csdn.net/tianyaleixiaowu/article/details/79787377 拓展: https://www.jianshu.com/p/d24b ...
- java for循环里面执行sql语句操作,有效结果只有一次,只执行了一次sql mybatis 循环执行update生效一次 实际只执行一次
java后台controller中,for循环执行数据库操作,但是发现实际仅仅执行了一次,或者说提交成功了一次,并没有实际的个数循环 有可能是同一个对象导致的 可以仔细看一下下面两段代码有什么区别 p ...
- for循环中进行联网请求数据、for循环中进行异步数据操作,数据排序错乱问题解决;
for循环中进行联网请求数据,由于网络请求是异步的,第一个网络请求还没有回调,第二次第三次以及后续的网络请求又已经发出去了,有可能后续的网络请求会先回调:这时我们接收到的数据的排序就会错乱:怎么才能让 ...
- 使用增强for循环遍历集合的时候操作集合的问题?
// 遍历一个list public static void printList(List<String> list){ for (String string : list) { list ...
- 快学Scala 第三课 (定长数组,变长数组, 数组循环, 数组转换, 数组常用操作)
定长数组定义: val ar = new Array[Int](10) val arr = Array("aa", "bb") 定长数组赋值: arr(0) = ...
- 【代码学习】PYTHON 列表循环遍历及列表常见操作
一.for循环 为了更有效率的输出列表的每个数据,可以使用循环来完成 代码: A = ['xiaoWang','xiaoZhang','xiaoHua'] for tempName in A: pri ...
- 在-for 循环里面如何利用ref 操作dom
由于dom 元素是在渲染之后才能操作,所以如果想取到dom元素,要放到mounted()这个生命周期函数里面,并且还要用this.$nextTick(function () {})
- 51nod 1050 循环数组最大子段和 单调队列优化DP
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值 然后求一遍最小值 ...
随机推荐
- extjs/js时间校验
//时间秒判断var re=/^(?:19|20)[0-9][0-9]-(?:(?:0[1-9])|(?:1[0-2]))-(?:(?:[0-2][1-9])|(?:[1-3][0-1])) (?:( ...
- centos7使用Gogs搭建Git服务器
一.初次接触Gogs,记录一下搭建过程 二.平台环境 Linux: CentOS7.5.1804 MySQL: 5.6.35 安装步骤: linux服务器新建git用户: 下载.解压gogs安装包: ...
- 梳理 Opengl ES 3.0 (五)shader运行原理
先来看看一张图 shader都是在运行时编译和执行的,每个shader都有一个main函数作为它的入口. vertex shader的功能有两个:一个是计算顶点坐标变换,另一个就是为片元shader计 ...
- Android之Audio和Video
The Android platform offers built-in encoding/decoding for a variety of common media types, so that ...
- Java开发环境配置时的dt.jar与tools.jar是什么(转载)
你了解dt.jar吗 很多人在初学Java的时候,都要配置环境变量.在配置CLASSPATH的时候,都会加上一个当前目录.,还有两个jar:dt.jar和tools.jar.其实好多人都不了解这两个j ...
- JS设置cookie,读取cookie,删除cookie
总结了一下cookie的使用,不全面.都是基础的知识,后期还会再添加. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...
- 整理base.css,重设浏览器样式
有的时候,可以把自己经常写的代码整理一下,分文别类,用的时候,拿过来直接用就可以了,可以节约很多时间,提高工作效率.所以,每个人都要有自己的代码库.点击下载 /* * @Author: liubeim ...
- 关于IE缓存
为了提高访问网页的速度,Internet Explorer浏览器会采用累积式加速的方法,将你曾经访问的网页内容(包括图片以及cookie文件等)存放在电脑里.这个存放空间,我们就称它为IE缓存.以后我 ...
- hdu 3496 Watch The Movie (二维背包)
Watch The Movie Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- Java —— Reflect反射机制
JAVA反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制. ...