首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

<linux kernel>plz do not use usleep(零)

2012-08-07 
linux kernelplz do not use usleep(0)!?最近发现很多hpc 领域的MPI程序中在用usleep(0)?,比较差异。?后

<linux kernel>plz do not use usleep(0)!

?


最近发现很多hpc 领域的MPI程序中在用usleep(0)?,比较差异。?后来问了之前做hpc?的同事?得到的答复是

一般用usleep(0)?的主要目的应该是:

CPU交出当前线程的执行权,让CPU去执行其他线程。也就是放弃当前线程的时间片,转而执行其他线程

?

我感觉很诧异。?Usleep(0)?来做这个事情?是POSIX要求的?还是一个意外的发现呢??我记得我之前都是用?sched_yield()?的啊。

于是有2个问题?

1 :usleep(0)?能不能让权,?

2?:如果可以和sched_yield?比到底谁更合适

我先man了一下usleep(0)?在linux上?,?

<linux kernel>plz do not use usleep(零)

Usleep?不应该大于?1s?这个是确定无疑的,?但是usleep(0)?的行为?就比较诡异了。Man?上没有明确提到?看来POSIX是不要求让权的,?这在QNX?MAC?等操作系统上?明确看到

Glibc?对于?usleep(0)?是


<linux kernel>plz do not use usleep(零)

同时linux?man?到明确写着


<linux kernel>plz do not use usleep(零)

那usleep?究竟有没有这个效果呢?。

先来看几个奇怪的现象:


<linux kernel>plz do not use usleep(零)

?执行shell?usleep?0?会明显的看到调用了


<linux kernel>plz do not use usleep(零)

?难道?

usleep(0)?=?sched_yield??

?


<linux kernel>plz do not use usleep(零)

?执行shell?usleep?x?(x!=0?)?会去调用naonsleep


<linux kernel>plz do not use usleep(零)

这就比较合理了,??之前猜测?usleep??就应该是调用了?nanosleep?,

?

然后写一个?c?函数调用来看看?

会发现?无论是0??还是?!0?都是调用的


<linux kernel>plz do not use usleep(零)
?

这就比较合理了,?看了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()的?

?

??
<linux kernel>plz do not use usleep(零)
?

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

?

)

?

根据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万次?的耗时如下


<linux kernel>plz do not use usleep(零)

?

?

在usleep(0)?的时候?调用10万次?的耗时如下

?


<linux kernel>plz do not use usleep(零)

?

?

延迟简直不是一个数量级。。?太可怕了,如果用于网络?那要丢多少UDP?,?TCP要做多少次拥塞避免。

?

?

在来看一下MPI中的这个问题


<linux kernel>plz do not use usleep(零)

?

MPI有个Yield宏,使用了?usleep(0)?,但是比较大的延迟

最后一张表的意思是,?应该尽可能的让CPU?100%,这样才算是yield。。

?

?

?

那为什么会造成usleep?如此延迟呢??

先看一下??trace的信息

Usleep?


<linux kernel>plz do not use usleep(零)

非常可怕??因为是非主动让权?调用了?deactivate_task()有简单操作系统知识的都知道

简直就恶魔。。。


<linux kernel>plz do not use usleep(零)

?

然而?sched_yield()


<linux kernel>plz do not use usleep(零)

非常干净??简直perfect!?

?

?

?

我们知道?在hpc?领域?MPI?的终极目地?就是耗尽CPU?

像usleep(0)?这么高的延迟?肯定是不能用来做让权的。?而且我也不觉得?usleep(0)?可以用在任何地方?,这是一个没保证,(你知道哪天glibc改了呢)?和极其不高效的方式?。

如果你是为了耗掉一个机器周期?,那直接asm?("nop")?,如果是为了让权建议所有使用usleep(0)?(注意是0,不是其他)的地方换成?sched_yield()?;

?

?

?

热点排行