结论:

  如果你是为了耗掉一个机器周期 ,那直接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)

  1. {
  2. hrtimer_init_sleeper(t, current);
  3. do {
  4. set_current_state(TASK_INTERRUPTIBLE);
  5. hrtimer_start_expires(&t->timer, mode);
  6. if (!hrtimer_active(&t->timer))
  7. t->task = NULL;
  8. if (likely(t->task))
  9. schedule();
  10. hrtimer_cancel(&t->timer);
  11. mode = HRTIMER_MODE_ABS;
  12. } while (t->task && !signal_pending(current));
  13. __set_current_state(TASK_RUNNING);
  14. return t->task == NULL;
  15. }

=======

补充一个 在2.6.9内核 或者可能之前的glibc实现中 usleep(0) 如果是基于 select (0) 这样的实现

在判断入参是0 之后会离开返回 不会调用 schelduer()的

=====================================================================

)

根据nanosleep 的 syscall ,发现

很明显的有 schedule(), 于是可以确定 usleep(0) 如果一切顺利确实会让权,那么和sched_yield比呢

于是写了一个 main

  1. #include <unistd.h>
  2. #include <sched.h>
  3. int main(){
  4. int j ;
  5. for(j=0; j<100000; j++)
  6. //usleep(0);
  7. sched_yield();
  8. }

在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() 调度的更多相关文章

  1. DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区

    DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区 DS Scheduler 0.7 发布,Linux 调度系统

  2. beego 0.9.0 中智能路由AutoRouter的使用方法及源码解读

    了解beego的开发者肯定知道,beego的路由设计来源于sinatra,原来是不支持自动路由的,每一个路由都要自己配置的,如: type MainController struct { beego. ...

  3. Nacos发布0.5.0版本,轻松玩转动态 DNS 服务

    阿里巴巴微服务开源项目Nacos于近期发布v0.5.0版本,该版本主要包括了DNS-basedService Discovery,对Java 11的支持,持续优化Nacos产品用户体验,更深度的与Sp ...

  4. Kafka: Producer (0.10.0.0)

    转自:http://www.cnblogs.com/f1194361820/p/6048429.html 通过前面的架构简述,知道了Producer是用来产生消息记录,并将消息以异步的方式发送给指定的 ...

  5. 支持边云协同终身学习特性,KubeEdge子项目Sedna 0.3.0版本发布!

    摘要:随着边缘设备数量指数级增长以及设备性能的提升,边云协同机器学习应运而生,以期打通机器学习的最后一公里. 本文分享自华为云社区<支持边云协同终身学习特性,KubeEdge子项目Sedna 0 ...

  6. 微软Visual Studio Code 0.8.0发布,新增多种主题

    月30日,Build 开发者大会上,正式宣布了 Visual Studio Code 项目;并将其定义为:一个运行于 Mac OS X.Windows和 Linux 之上的,针对于编写现代 Web 和 ...

  7. Ubuntu14.04 64位机上安装cuda8.0 cudnn5.0操作步骤 - 网络资源是无限的

    查看Ubuntu14.04 64位上显卡信息,执行: lspci | grep -i vga lspci -v -s 01:00.0 nvidia-smi 第一条此命令可以显示一些显卡的相关信息:如果 ...

  8. Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)

    Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...

  9. 《征服 C 指针》摘录1:什么是空指针?区分 NULL、0 和 '\0'

    一.什么是空指针? 空指针 是一个特殊的指针值. 空指针 是指可以确保没有向任何一个对象的指针.通常使用宏定义 NULL 来表示空指针常量值. 空指针 确保它和任何非空指针进行比较都不会相等,因此经常 ...

随机推荐

  1. 20175313 张黎仙《Java程序设计》第十周学习总结

    目录 一.教材学习内容总结 二.教材学习中的问题和解决过程 三.代码调试中的问题和解决过程 四.代码托管 五.心得体会 六.学习进度条 七.参考资料 一.教材学习内容总结 第十二章内容 主要内容 杂项 ...

  2. Linux设备驱动程序 之 后备高速缓存

    设备驱动程序常常会反复的分配很多相同大小的内存块:内核实现了后备高速缓存来对此进行支持,以反复的使用这些相同的内存块: 创建 Linux内核的高速缓存管理有时被称为“slab分配器”:因此,相关函数和 ...

  3. [转发]Android视频技术探索之旅:美团外卖商家端的实践

    美团技术团队 2019-09-12 20:02:11 背景 2013年美团外卖成立,至今一直迅猛发展.随着外卖业务量级与日俱增,单一的文字和图片已无法满足商家的需求,商家迫切需要更丰富的商品描述手段吸 ...

  4. 牛顿法与拟牛顿法(四) BFGS 算法

    转自 https://blog.csdn.net/itplus/article/details/21897443

  5. Get Raster Properties获得栅格的信息

    Summary Returns the properties of a raster dataset. Usage The property returned will be displayed in ...

  6. kotlin 泛型约束

    fun <T:Comparable<T>> sort(list :List<T>){} 冒号之后指定的类型就是泛型参数的上界,对于泛型参数T,只允许使用Compar ...

  7. code review 20190705

    命名规范: 做了什么? 目的是什么? 在什么基础上进行? 注释说明 sql update,where 先行????? 警告: 清空所有警告:所有隐藏比较深入的bug,都是由警告带来的 + 忽略警告 枚 ...

  8. JAVA 基础编程练习题41 【程序 41 猴子分桃】

    41 [程序 41 猴子分桃] 题目:海滩上有一堆桃子,五只猴子来分.第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把 多的一个扔入海中,拿走了一份.第二只猴子把剩下的桃子又平均分成五份,又多了 ...

  9. 在线word转html

    http://www.docpe.com/word/word-to-html.aspx

  10. 从0开始自己用C语言写个shell__01_整体的框架以及fork和exec族函数的理解

    最近才忙完了一个操作系统的作业,让我们用C语言实现一个Shell.总的来说,其实就是让我们 对系统调用有比较深的了解. 首先 介绍一下我的Shell 所实现的功能.1.运行可执行程序 即输入某个 标志 ...