sleep(0)、usleep(0)与sched_yield() 调度
结论:
如果你是为了耗掉一个机器周期 ,那直接asm ("nop") ,
如果是为了让权,建议把 所有使用 usleep(0) 换成 sched_yield() ;
最近发现很多hpc 领域的MPI程序中在用usleep(0) ,比较差异。 后来问了之前做hpc 的同事 得到的答复是
一般用usleep(0) 的主要目的应该是:
CPU交出当前线程的执行权,让CPU去执行其他线程。也就是放弃当前线程的时间片,转而执行其他线程
我感觉很诧异。 Usleep(0) 来做这个事情 是POSIX要求的 还是一个意外的发现呢?
于是有2个问题
1 :usleep(0) 能不能让权,
2 :如果可以,那么和sched_yield 比到底谁更合适
我先man了一下usleep(0) 在linux上 ,
NOTES
The type useconds_t is an unsigned integer type capable of holding integers in the range [,]. Programs will be more
portable if they never mention this type explicitly. Use #include <unistd.h>
...
unsigned int usecs;
...
usleep(usecs); The interaction of this function with the SIGALRM signal, and with other timer functions such as alarm(), sleep(),
nanosleep(), setitimer(), timer_create(), timer_delete(), timer_getoverrun(), timer_gettime(), timer_settime(),
ualarm() is unspecified.
先来看几个奇怪的现象:
执行shell usleep 0 会明显的看到调用了
难道
usleep(0) = sched_yield?
而
执行shell usleep x (x!=0 ) 会去调用naonsleep
这就比较合理了, 之前猜测 usleep 就应该是调用了 nanosleep ,
然后写一个 c 函数调用来看看
会发现 无论是0 还是 !0 都是调用的
这就比较合理了, 看了glibc源码 也验证了确实是 封装naosleep
那第一个问题在linux 上就变成 naosleep(0,0) 是不是会去让权了, 他和sheld_yield 的区别。
在.18 之后 应该naosleep 都是基于 hrtimer的机制实现了 (
==============================================================
do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
- {
- hrtimer_init_sleeper(t, current);
- do {
- set_current_state(TASK_INTERRUPTIBLE);
- hrtimer_start_expires(&t->timer, mode);
- if (!hrtimer_active(&t->timer))
- t->task = NULL;
- if (likely(t->task))
- schedule();
- hrtimer_cancel(&t->timer);
- mode = HRTIMER_MODE_ABS;
- } while (t->task && !signal_pending(current));
- __set_current_state(TASK_RUNNING);
- return t->task == NULL;
- }
=======
补充一个 在2.6.9内核 或者可能之前的glibc实现中 usleep(0) 如果是基于 select (0) 这样的实现
在判断入参是0 之后会离开返回 不会调用 schelduer()的
=====================================================================
)
根据nanosleep 的 syscall ,发现
很明显的有 schedule(), 于是可以确定 usleep(0) 如果一切顺利确实会让权,那么和sched_yield比呢
于是写了一个 main
- #include <unistd.h>
- #include <sched.h>
- int main(){
- int j ;
- for(j=0; j<100000; j++)
- //usleep(0);
- sched_yield();
- }
在sched_yield() 的时候 调用10万次 的耗时如下
在usleep(0) 的时候 调用10万次 的耗时如下
延迟简直不是一个数量级。。 太可怕了,如果用于网络 那要丢多少UDP , TCP要做多少次拥塞避免。
在来看一下MPI中的这个问题
http://trac.mcs.anl.gov/projects/mpich2/ticket/1597\
MPI有个Yield宏,使用了 usleep(0) ,但是比较大的延迟
最后一张表的意思是, 应该尽可能的让CPU 100%,这样才算是yield。。
那为什么会造成usleep 如此延迟呢?
先看一下 trace的信息
Usleep
非常可怕 因为是非主动让权 调用了 deactivate_task()有简单操作系统知识的都知道
简直就恶魔。。。
然而 sched_yield()
非常干净 简直perfect!
我们知道 在hpc 领域 MPI 的终极目地 就是耗尽CPU
像usleep(0) 这么高的延迟 肯定是不能用来做让权的。 而且我也不觉得 usleep(0) 可以用在任何地方 ,这是一个没保证,(你知道哪天glibc改了呢) 和极其不高效的方式 。
如果你是为了耗掉一个机器周期 ,那直接asm ("nop") ,如果是为了让权建议所有使用usleep(0) (注意是0,不是其他)的地方换成 sched_yield() ;
sleep(0)、usleep(0)与sched_yield() 调度的更多相关文章
- DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区
DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区 DS Scheduler 0.7 发布,Linux 调度系统
- beego 0.9.0 中智能路由AutoRouter的使用方法及源码解读
了解beego的开发者肯定知道,beego的路由设计来源于sinatra,原来是不支持自动路由的,每一个路由都要自己配置的,如: type MainController struct { beego. ...
- Nacos发布0.5.0版本,轻松玩转动态 DNS 服务
阿里巴巴微服务开源项目Nacos于近期发布v0.5.0版本,该版本主要包括了DNS-basedService Discovery,对Java 11的支持,持续优化Nacos产品用户体验,更深度的与Sp ...
- Kafka: Producer (0.10.0.0)
转自:http://www.cnblogs.com/f1194361820/p/6048429.html 通过前面的架构简述,知道了Producer是用来产生消息记录,并将消息以异步的方式发送给指定的 ...
- 支持边云协同终身学习特性,KubeEdge子项目Sedna 0.3.0版本发布!
摘要:随着边缘设备数量指数级增长以及设备性能的提升,边云协同机器学习应运而生,以期打通机器学习的最后一公里. 本文分享自华为云社区<支持边云协同终身学习特性,KubeEdge子项目Sedna 0 ...
- 微软Visual Studio Code 0.8.0发布,新增多种主题
月30日,Build 开发者大会上,正式宣布了 Visual Studio Code 项目;并将其定义为:一个运行于 Mac OS X.Windows和 Linux 之上的,针对于编写现代 Web 和 ...
- Ubuntu14.04 64位机上安装cuda8.0 cudnn5.0操作步骤 - 网络资源是无限的
查看Ubuntu14.04 64位上显卡信息,执行: lspci | grep -i vga lspci -v -s 01:00.0 nvidia-smi 第一条此命令可以显示一些显卡的相关信息:如果 ...
- Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...
- 《征服 C 指针》摘录1:什么是空指针?区分 NULL、0 和 '\0'
一.什么是空指针? 空指针 是一个特殊的指针值. 空指针 是指可以确保没有向任何一个对象的指针.通常使用宏定义 NULL 来表示空指针常量值. 空指针 确保它和任何非空指针进行比较都不会相等,因此经常 ...
随机推荐
- python异常链
习惯使用java开发,在java开发里有异常链概念和重新抛出异常,在python是怎么实现的呢? 1.异常链 1.1.java实现 public static void test1() throws ...
- tomcat发布web项目
转:https://www.cnblogs.com/skyblue-li/p/7888951.html Tomcat是一种Web服务器,我们自己做好了一个Web项目,就可以通过Tomcat来发布.服务 ...
- ROS机器人开发实践学习笔记3
摘要: 刚刚开始学习ROS,打算入机器人的坑了,参考教材是<ROS及其人开发实践>胡春旭编著 机械工业出版社 华章科技出品.本来以为可以按照书上的步骤一步步来,但是,too young t ...
- JAVA基础知识|异常
一.基础知识 处理异常,java提供了一个优秀的解决方案:异常处理机制. java把异常当作对象来处理,所有的异常都是由Throwable继承而来,但在下一层立即分解为两个分支:Error和Excep ...
- jdbc相比于hibernate的弊端
1.编程人员必须既懂Java语言,又懂SQL语言,才能编写数据库访问代码.(感觉用不用hibernate,SQL都要会呀) 2.程序代码中嵌入大量字符串形式的SQL语句,降低了程序代码的可读性. 3. ...
- PostgreSQL判断一个表是否存在
postgresql判断一个表是否存在: 方法一: select count(*) from pg_class where relname = 'tablename'; 方法二: select cou ...
- Qt自定义委托在QTableView中绘制控件、图片、文字
自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...
- zookeeper系列 (第三章 :zookeeper 的使用)
接上一章,在启动客户端之后,开始通过命令操作zookeeper 服务. 一:zookeeper 的基础命令 1.通过zkCli.sh 命令与主机建立一个会话 2.开始在会话中执行命令:写入Znode. ...
- UNIX 历史问题 分布式系统的Thundering Herd效应 惊群效应
https://uwsgi-docs.readthedocs.io/en/latest/articles/SerializingAccept.html One of the historical pr ...
- centos下使用virtualenv建立python虚拟环境
在centos使用python3的virtualenv,先用yum install python3 安装后pip3也已经安装好了,pip3 install virtualenv, 在系统中新建一个空文 ...