Sådan får du udførelsestidspunktet for et script

Kerneplads vs. brugerplads
CS Arkitektur

For et par uger siden arbejdede jeg på et sjovt projekt til en dørmonitor med Raspberry Pi 3 model B og shell scripting. Jeg har for nylig tilsluttet et kamera til Pi og opdateret scriptet, så der bliver taget et billede, når døren åbnes og sendes som en vedhæftet fil i e-mail-meddelelsen.

Et af de problemer, jeg løb ind i, var, at udførelsestiden af ​​scriptet steg betydeligt fra få sekunder indledningsvis til 17,58 sek. Jeg var i stand til at identificere og isolere udførelsestiden for hver linje på scriptet. Jeg blev klar over, at raspistill-kommandoen tog 5. 87 sekunder at udføre. Hvilket resultat mangler helt for at fange et foto af personen, der åbner døren.

hvordan man reducerer udførelsestiden for raspistill

Et simpelt raspistill efterfulgt af "- hjælp" -tag på terminalen gav mere information om billedparameterkommandoer:

pi @ raspberrypi: ~ $ raspistill - hjælp
Kører kameraet til et bestemt tidspunkt, og tag JPG-optagelse ved slutningen, hvis det ønskes
brug: raspistill [indstillinger]
Billedparameterkommandoer
...
-t, - timeout: Tid (i ms) før tager billedet og lukker ned (hvis ikke angivet, indstillet til 5s)

Jeg var i stand til at reducere udførelsestiden for raspistill til få millisekunder ved at specificere tiden, før billedet tages på scriptet som følger:

Sådan får du udførelsestidspunktet for et script effektivt

Under denne proces lærer jeg om tidskommandoen, der bruges til at få den tid, det tager for en anden kommando eller script at udføre:

time YourScript.sh // få udførelse af et script
tid ls // få udførelsestid for ls-kommandoen

hvilket gav følgende resultat:

Terminalskærmbillede af kommandoen “time ls”

Nu kan du bemærke, at tidskommandoen giver en reel, bruger og systemtid. Forståelse af brugernes plads vs Kernelrum betyder noget. En af disse ting er ikke som den anden. Reel henviser til faktisk forløbet tid; Bruger og Sys henviser til CPU-tid, der kun bruges af processen.

Real, User og Sys processstidsstatistik
  • Real er vægtur - tid fra start til slut af opkaldet. Dette er alt forløbne tid, inklusive tidsskiver, der bruges af andre processer, og den tid, processen bruger blokeret (for eksempel hvis den venter på, at I / O er afsluttet).
  • Bruger er den mængde CPU-tid, der bruges i brugertilstandskode (uden for kernen) inden for processen. Dette er kun den faktiske CPU-tid, der bruges til at udføre processen. Andre processer og tid, som processen bruger blokeret, tæller ikke med i dette tal.
  • Sys er den mængde CPU-tid, der bruges i kernen i processen. Dette betyder at udføre CPU-tid brugt i systemopkald i kernen i modsætning til bibliotekskode, der stadig kører i brugerrum. Ligesom 'bruger' er dette kun CPU-tid, der bruges af processen. Se nedenfor for en kort beskrivelse af kernetilstand (også kendt som 'vejleder' -tilstand) og systemopkaldsmekanismen.

User + Sys fortæller dig, hvor meget faktisk CPU-tid din proces har brugt. Bemærk, at dette er på tværs af alle CPU'er, så hvis processen har flere tråde (og denne proces kører på en computer med mere end en processor), kan den potentielt overskride den vægttid, der er rapporteret af Real (som normalt forekommer). Bemærk, at i tallene disse tal inkluderer bruger- og Sys-tiden for alle underordnede processer (og deres efterkommere), også når de kunne have været samlet, f.eks. ved vent (2) eller ventepid (2), skønt det underliggende systemopkald returnerer statistikkerne for processen og dets børn separat.

Oprindelse af statistikker rapporteret efter tid (1)

Statistikken rapporteret med tiden samles fra forskellige systemopkald. 'Bruger' og 'Sys' kommer fra ventetid (2) eller tidspunkter (2), afhængigt af det særlige system. 'Rigtig' beregnes fra et start- og sluttidspunkt samlet fra gettimeofday (2) -opkaldet. Afhængig af systemets version kan forskellige andre statistikker, såsom antallet af kontekstkontakter, også indsamles efter tiden.

På en multi-processor-maskine kan en multi-threaded proces eller en proces, der gaffer børn, have en forløbet tid mindre end den samlede CPU-tid - da forskellige tråde eller processer kan køre parallelt. De rapporterede tidsstatistikker kommer også fra forskellige oprindelser, så tider, der er registreret til meget korte kørselsopgaver, kan være genstand for afrundingsfejl, som eksemplet, der er givet af den originale plakat, viser.

En kort grundbog om tilstanden Kernel vs. bruger

I Unix eller et hvilket som helst operativsystem med beskyttet hukommelse henviser 'Kernel' eller 'Supervisor' -tilstand til en privilegeret tilstand, som CPU'en kan betjene i. Visse privilegerede handlinger, der kan påvirke sikkerhed eller stabilitet, kan kun udføres, når CPU'en kører i dette mode. Disse handlinger er ikke tilgængelige for applikationskode.

Et eksempel på en sådan handling kan være manipulation af MMU for at få adgang til adresserummet i en anden proces. Normalt kan brugertilstandskode ikke gøre dette (med god grund), skønt den kan anmode om delt hukommelse fra kernen, som kunne læses eller skrives af mere end en proces. I dette tilfælde anmodes eksplicit den delte hukommelse fra kernen gennem en sikker mekanisme, og begge processer skal eksplicit knyttes til den for at bruge den.

Den privilegerede tilstand omtales normalt som 'kernel' -tilstand, fordi kernen udføres af CPU'en, der kører i denne tilstand. For at skifte til kernetilstand skal du udstede en specifik instruktion (ofte kaldet en fælde), der skifter CPU til at køre i kernetilstand og kører kode fra et specifikt sted, der er indeholdt i en springtabel.

Af sikkerhedsmæssige årsager kan du ikke skifte til kernetilstand og udføre vilkårlig kode - fælderne styres gennem en tabel med adresser, der ikke kan skrives til, medmindre CPU'en kører i overvågningstilstand. Du fælder med et eksplicit fældenummer, og adressen bliver slået op i springtabellen; kernen har et begrænset antal kontrollerede indgangspunkter.

'System'-opkaldene i C-biblioteket (især dem, der er beskrevet i afsnit 2 på man-siderne), har en brugertilstandskomponent, hvilket er, hvad du faktisk kalder fra dit C-program. Bag kulisserne udsender de muligvis et eller flere systemopkald til kernen for at udføre specifikke tjenester såsom I / O, men de har stadig også kode, der kører i brugertilstand.

Det er også meget muligt at udstede en fælde til kernetilstand fra enhver bruger-plads-kode, hvis det ønskes, selvom du muligvis skal skrive et uddrag af samlingssprog for at opsætte registre korrekt for opkaldet. En side, der beskriver systemopkaldene leveret af Linux-kernen og konventionerne til opsætning af registre kan findes her.

Mere om 'sys'

Der er ting, som din kode ikke kan gøre fra brugertilstand - ting som tildeling af hukommelse eller adgang til hardware (HDD, netværk osv.). Disse er under overvågning af kernen, og det alene kan gøre dem. Nogle operationer, som du udfører (som malloc orfread / fwrite), påkalder disse kernefunktioner, og det tæller som 'sys' -tid. Desværre er det ikke så simpelt som "hvert opkald til malloc tælles i 'sys' tid".

I C bruges biblioteksfunktionen malloc til at tildele en hukommelsesblok på dyngen. Programmet får adgang til denne hukommelsesblok via en markør, som malloc returnerer. Når hukommelsen ikke længere er nødvendig, føres markøren til fri, som omfordeler hukommelsen, så den kan bruges til andre formål.

Opkaldet til malloc udfører en vis behandling af sig selv (tælles stadig i 'brugertid') og derefter et eller andet sted undervejs kan det kalde funktionen i kerne (tælles i 'sys' tid). Efter at have vendt tilbage fra kerneopkaldet, vil der være lidt mere tid i 'bruger' og derefter vender malloc tilbage til din kode. Hvad angår hvornår skiftet sker, og hvor meget af det der bruges i kernetilstand ... kan du ikke sige. Det afhænger af implementeringen af ​​biblioteket. Andre tilsyneladende uskyldige funktioner kan også bruge malloc og lignende i baggrunden, som igen vil have noget tid i 'sys' derefter.

Nogle indhold i denne artikel er en kombination af svar, der oprindeligt blev sendt på Stack Overflow
Hvis du nød denne artikel, kan du muligvis også lide "Sådan oprettes en tovejs-app til Internet of Things / Chat med Python"
Giv det et par klapper til support!
Skål !!!