Pielikums B: Datoru pulksteņi

Pēdējais mainījis Administrator 2011-06-06 17:16

Pielikums B: Datoru pulksteņi

Tā kā vairums piemēru šajā grāmatā mēra laika intervālu, mums sīkāk jāapraksta #term("laika uzturēšana", "timekeeping"), ko izmanto pašreizējās UNIX sistēmas. Šis apraksts ir lietojams sistēmām, kuras atspoguļotas šīs grāmatas piemēros un vairumam citu UNIX sistēmu. Papildu nianses ir dotas 3.4. un 3.5.nodaļās [Leffler et al. 1989].

#term("Aparatūra", "hardware") ģenerē pulksteņa pārtraukumu ar noteiktu frekvenci. Priekš Sun SPARCs un Intel 80386 pārtraukumi notiek ik pēc 10 milisekundēm.

Jāatzīmē, ka vairums datoru izmanto #term("nekompensētu kristālu oscilatoru", "uncompensated_crystal_oscillator"), lai ģenerētu šos pārtraukumus. Kā atzīmēts RFC 1305 7.tabulā [Mills 1992], nav vēlēšanās uzdot jautājumu, kāda ir šāda oscilatora nobīde 1 dienas laikā. Tas nozīmē, ka nedaudzi datori uztur precīzu laiku (t.i. pārtraukumi nenotiek precīzi ik pēc 10 milisekundēm). 0.01% #term("kļūdas pielaide", "tolerance") dod dienas laikā 8.64 sekunžu kļūdu. Lai laiku mērītu precīzāk (1) vajadzīgs labāks oscilators, (2) ārējs laika avots ar lielāku precizitāti (piemēram, laika avots, ko atbalsta #term("Globālās pozicionēšanas sistēmas", "Global_Positioning_System") (GPS) satelīti vai (3) piekļuve pa Internetu sistēmām, kurām ir precīzāki pulksteņi. Pēdējo no šīm iespējām nodrošina #term("tīkla laika protokols", "Network_Time_Protocol"), kurš detalizēti aprakstīts RFC 1305 un kura izklāsts neietilpst šajā grāmatā.

Cits izplatīts laika kļūdu avots UNIX'a sistēmās ir tāds, ka 10 ms pulksteņa pārtraukumi vienīgi piedāvā kodolam palielināt mainīgo, kurš uztur tekošo laika vērtību. Ja kodols pazaudē pārtraukumu (t.i. tas ir pārāk aizņemts visas 10ms līdz nākošajam pārtraukumam), pulkstenis zaudēs 10 milisekundes. Šāda veida zaudētie #term("pārtraukumi", "interrupt") bieži liek UNIX'a sistēmām zaudēt laiku.

Lai gan pulksteņa pārtraukumi atnāk aptuveni ik pēc 10 ms, jaunākas sistēmas, piemēram SPARC, sasniedz augstākas #term("precizitātes", "resolution") taimeri laika intervālu mērīšanai. Programmai tcpdump, izmantojot NIT draiveri (kas aprakstīts Pielikumā A), ir piekļuve šim augstākas precizitātes taimerim. Uz SPARC šis taimeris dod mikrosekundes precizitāti. Piekļuve šim augstākas precizitātes taimerim ir dota arī lietotāja procesiem, izmantojot gettimeofday(2) funkciju.

Autors veica sekojošu eksperimentu. Tika darbināta programma, kura izsauca gettimeofday funkciju 10000 reizes ciklā, noglabājot ikreiz atgriežamo vērtību masīvā. Cikla beigās 9999 laika intervālu garumi tika izdrukāti. SPARC ELC mašīnai šo garumu sadalījums parādīts B.1.attēlā.

#pic("f_B_1.gif", "200")
B.1.attēls: Laika sadalījums, kas nepieciešams, lai gettimeofday uz SPARC ELC izsauktu 10000 reizes.

Pilnais pulksteņa laiks, kas nepieciešams šīs programmas darbināšanai bija 0.38 sekundes uz citādi nenoslogotas sistēmas. No šejienes seko, ka viena gettimeofday izsaukuma apstrādes laiks ir aptuveni 37 mikrosekundes. Tā kā ELC ātrdarbību novērtē ar apmēram 21 MIPS (miljoni instrukciju sekundē), 37 mikrosekundes atbilst aptuveni 800 instrukcijām. Tas šķiet saprātīgi, lai kodols apstrādātu sistēmas izsaukumu no lietotāja procesa, izpildītu sistēmas izsaukumu, pārkopētu 8 rezultāta baitus un atgrieztos lietotāja procesā. (MIPS novērtējumi ir strīdīgi un ir grūti izmērīt pašreizējo sistēmu ātrdarbību kā instrukciju laikus. Tas, ko mēs cenšamies izdarīt, ir mēģināt iegūt tuvinātu priekšstatu un apskatīties vai skaitliskie rezultāti varētu būt ar jēgu.

No šī vienkāršā eksperimenta var secināt, ka getttimeofday atgrieztās vērtības tik tiešām dod mikrosekundes precizitāti.

Darbinot līdzīgus testus uz SVR4/386 rezultāti toties ir atšķirīgi. Tas ir tādēļ, ka daudzas 386 UNIX sistēmas, piemēram SVR4 tikai skaita 10 milisekužu pulksteņa pārtraukumus, un necenšas sniegt augstāku precizitāti. B.2.attēls ir sadalījums 9999 atširībām uz SVR4 ar 25 Mhz 80386.

#pic("f_B_2.gif", "200")
B.2.attēls: Laika sadalījums, kas nepieciešams, lai gettimeofday uz SVR4/386 izsauktu 10000 reizes.

Šīs vērtības patiesībā laiku ir falšas, jo starpības parasti sanāk mazākas nekā 10 milisekundes, ko mašīna uztver kā 0. Šāda veida sistēmām mēs varam vienīgi mērīt pulksteņa laiku uz #term("nenoslogotas sistēmas", "idle_system") un izdalīt to ar ciklu skaitu. Tas dod augšējo robežu, jo tas ietver sevī laiku, kas vajadzīgs, lai printf izsauktu 9999 reizes, ierakstot rezultātus failā. (SPARC gadījumā #picref("f_B_1.gif", "B.1.attēlā") intervālu garumi neietvēra sevī printf laikus, jo visas 10000 vērtības vispirms tika iegūtas, savukārt rezultāti izdrukāti pašās beigās.) Uz SVR4 pulksteņa laiks bija 3.15 sekundes, kas nozīmē, ka 315 mikrosekundes tika iztērētas sistēmas (gettimeofday) izsaukumam. Šis sistēmas izsaukuma laiks, kas ir apmēram 8.5 reizes lēnāks nekā SPARC šķiet apmēram pareizs.

BSD/386 1.0.versija dod SPARC'am līdzīgu mikrosekunžu precizitāti. Tā lasa 8253 pulksteņa reģistru un rēķina mikrosekunžu skaitu kopš pēdējā pulksteņa tikšķa. Šo mehānismu padara pieejamu procesiem, kuri sauc gettimeofday un kodola moduļiem, piemēram BSD pakešu filtram.

Saistībā ar tcpdump šie skaitļi nozīmē, ka mēs varam ticēt milisekunžu un submilisekunžu vērtībām, kas tiek izdrukātas uz SPARC un BSD/386 sistēmām, bet vērtības, ko tcpdump izdrukā uz SVR4/386 vienmēr būs 10 ms daudzkārtņi. Citām programmām, kuras drukā #term("pilna ceļa", "round_trip") laikus, piemēram ping (7.nodaļa) un traceroute (8.nodaļa), uz SPARC un BSD/386 sistēmām varam ticēt milisekužu vērtībām, kuras tiek izvadītas, bet vērtības, ko izdrukā no SVR4/386 vienmēr būs 10 daudzkārtņi. Lai mērītu kaut ko līdzīgu ping laikam uz LAN, kas 7.nodaļā izrādījās ir aptuveni 3 ms, prasa darbināt ping uz SPARC vai BSD/386.

Daži piemēri šajā grāmatā tika darbināti uz BSD/386 v. 0.9.4, kas ir līdzīgs SVR4 tanī ziņā, ka tas dod 10 ms pulksteņa precizitāti. Kad mēs parādām tcpdump izvadi no šīs sistēmas, mēs parādām tikai divus ciparus aiz komata. jo tā ir šajā sistēmā pieejamā precizitāte.

Tagi:
Izveidojis Kalvis Apsītis 2008-03-26 18:41
    
This wiki is licensed under a Creative Commons 2.0 license
XWiki Enterprise 6.4 - Documentation