|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
有些人号称用过十几种甚至几十种linux,向人谈论起来头头是到,好像懂的很多。
起首,我会说不包管你在利用者形式(user-mode)中实行的路程(process)可以准确地把持时序由于Linux是个多工的功课情况.你在实行中的路程(process)随时会由于各类缘故原由被停息约莫10毫秒到数秒(在体系负荷十分高的时分).但是,对於年夜多半利用I/O埠的使用而言,这个提早工夫实践上算不了什麽.要延长提早工夫,你得利用函式nice将你在实行中的路程(process)设定成高优先权(请参考nice(2)利用申明文件)或利用立即排程法(real-timescheduling)(请看上面).
假如你想取得比在一样平常利用者形式(user-mode)中实行的路程(process)还要准确的时序,有一些办法可让你在利用者形式(user-mode)中做到`立即排程的增援.Linux2.x版本的中心中有软体体例的立即排程增援;具体的申明请参考sched_setscheduler(2)利用申明文件.有一个特别的中心增援硬体的立即排程;
(Sleeping):sleep()与usleep()
如今,让我们入手下手较复杂的时序函式呼唤.想要提早数秒的工夫,最好的办法也许是利用函式sleep().想要提早最少数十毫秒的工夫(10ms仿佛已经是最短的提早工夫了),函式usleep()应当可使用.这些函式是让出CPU的利用权给其他想要实行的路程(processes)(``本人歇息往了),以是没有华侈失落CPU的工夫.细节请参考sleep(3)与usleep(3)的申明文件.
假如让出CPU的利用权因此使得工夫提早了约莫50毫秒(这取决於处置器与呆板的速率,和体系的负荷),就华侈失落CPU太多的工夫,由于Linux的排程器(scheduler)(单就x86架构而言)在将把持权发回给你的路程(process)之前一般最少要消费10-30毫秒的工夫.因而,短工夫的提早,利用函式usleep(3)所失掉的提早了局一般会年夜於你在参数所指定的值,约莫最少有10ms.
nanosleep()
在Linux2.0.x一系列的中心刊行版本中,有一个新的体系呼唤(systemcall),nanosleep()(请参考nanosleep(2)的申明文件),他让你可以歇息或提早一个短的工夫(数微秒或更多).
假如提早的工夫<=2ms,若(且唯若)你实行中的路程(process)设定了软体的立即排程(就是利用函式tt/sched_setscheduler()/),呼唤函式nanosleep()时不是利用一个劳碌回圈来提早工夫;就是会像函式usleep()一样让出CPU的利用权歇息往了.
这个劳碌回圈利用函式udelay()(一个驱动程式常会用到的中心外部的函式)来告竣,而且利用BogoMips值(BogoMips能够正确量测这类劳碌回圈的速率)来盘算回圈提早的工夫长度.其怎样举措的细节请参考/usr/include/asm/delay.h).
利用I/O埠来提早工夫
另外一个提早数微秒的办法是利用I/O埠.就是从埠位址0x80输出或输入任何byte的材料(请参考后面)守候的工夫应当几近只需1微秒这要看你的处置器的型别与速率.假如要提早数微秒的工夫你能够将这个举措多做几回.在任何尺度的呆板上输入材料到该埠位址应当不会有不良的後果□对(并且有些中心的设备驱动程式也在利用他).{in|out}[bw]_p()等函式就是利用这个办法来发生工夫提早的(请参考档案asm/io.h).
实践上,一个利用到埠位址□围为0-0x3ff的I/O埠指令几近只需1微秒的工夫,以是假如你要云云做,比方,间接利用并列埠,只需加上几个inb()函式从该埠位址□围读进byte的材料便可.
利用组合言语来提早工夫
假如你晓得实行程式地点呆板的处置器型别与时钟速率,你能够实行某些组合言语指令以便取得较短的提早工夫(可是记着,你在实行中的路程(process)随时会被停息,以是偶然提早的工夫会比实践长).以下面的表格所示,外部处置器的速率决意了所要利用的时钟周期数;如,一个50MHz的处置器(486DX-50或486DX2-50),一个时钟周期要消费1/50000000秒(=200奈秒).
指令i386时钟周期数i486时钟周期数nop31xchg%ax,%ax33or%ax,%ax21mov%ax,%ax21add%ax,021
(对不起,我不晓得Pentiums的材料,也许与i486靠近吧.我没法在i386的材料上找到只消费一个时钟周期的指令.假如可以就请利用消费一个时钟周期的指令,要否则就利用管线手艺的旧式处置器也是能够延长工夫的.)
下面的表格中指令nop与xchg应当不会有不良的後果.指令最後大概会改动旗帜暂存器的内容,可是这不妨由于gcc会处置.指令nop是个好的选择.
想要在你的程式中利用到这些指令,你得利用asm("instruction").指令的语法就好像下面表格的用法;假如你想要在单一的asm()叙说中利用多个指令,可使用分号将他们离隔.比方,asm("nop;nop;nop;nop")会实行四个nop指令,在i486或Pentium处置器中会提早四个时钟周期(或是i386会提早12个时钟周期).
gcc会将asm()翻译成单行组合言语程式码,以是不会有呼唤函式的负荷.
在Intelx86架构中不成能有比一个时钟周期还短的工夫提早.
在Pentiums处置器上利用函式rdtsc
对於Pentiums处置器而言,你可使用上面的C言语程式码来获得自从前次从头开机到如今经由了几个时钟周期:
--------------------------------------------------------------------------------
extern__inline__unsignedlonglongintrdtsc(){unsignedlon
12下一页
只要了解了Linux的基础之后,应该就可以很轻易的解决掉这方面的问题。而有些朋友们常常一接触Linux就是希望构架网站,根本没有想到要先了解一下Linux的基础。这是相当困难的。 |
|