URL: https://www.overclockers.at/linux/unter-linux-die-cpu-last-in-anzeigen-nicht-interaktiv-mit-kernellast_247071/page_1 - zur Vollversion wechseln!
Grüß euch!
Ich versuch grade mir einfachen Code in bash zu bauen, der mir die Gesamtlast einer CPU über alle Threads bzw. Kerne in % ausgibt. Mein aktueller Ansatz ist folgender:
(Ist nur ein Teil einer größeren Kette von Kommandos, daher ned so auf die Ausgabeformatierung schauen..)Code:echo -ne 'cpu load: ' $((`ps -A -o pcpu | tail -n+2 | paste -sd+ | bc | \\ cut -d'.' -f1` / `cat /proc/cpuinfo | grep processor | wc -l`))'%. '
ich weisz nicht, ob ich die Frage verstehe, aber `mpstat 1 1` und `top -b -n1` (beide ggf. mit zusaetzliche Optionen zur Beeinflussung der Ausgabe) kennst du?
Ich hab mpstat (und top) probiert und keine von Kernelmodulen verursachten Lasten damit ausgegeben bekommen, ich werd's aber morgen nochmal probieren.
Sache is die: Wenn eine virtuelle Maschine Last verursacht, dann ist die bei mir im Kernelspace (da sind halt irgendwelche Kernelmodule geladen die dann den Code innerhalb der VM ausführen). Da konnte ich alle Kerne auslasten, z.B. top hat mir das einfach nicht angezeigt. Wenn ich k.A., den GCC oder so anwerfe, kann ich die Last sofort bestimmen.
Aber ich schau's mir wie gesagt morgen nochmal mit den von dir angegebenen Optionen an...
Auch Kernel-Thread-CPU-Accounting schlaegt sich in procfs an den zu erwartenden Stellen nieder, und wird dementsprechend korrekt von top, mpstat und Konsorten (als "System Time") ausgewertet.
Edith meint noch: Wenn du die interessanten PIDs vorab weiszt, ist `pidstat` das Tool der Wahl.
Oder du liest /proc/<pid>/stat selbst; ist mit scanf(3) unkompliziert.
Hmm, muß ich mir morgen anschauen, solange ich einen hinreichend genauen Prozentwert (also sowas wie "78%") draus ermitteln kann, indem ich die entsprechenden Kernel/Userspace Lasten mit der Bash zusammenrechne, würde mir das schon reichen.
Die PIDs sind leider nicht zielführend, weil ich es nicht pro Prozeß, sondern pro komplette Maschine ausgeben will (also die gesamte CPU Last auf einer Box).
Hmm, per mpstat bekomme ich es, da hast du Recht. Per top nicht wie gezeigt, weil top einfach seltsam zählt, siehe unten. Najo, bei 33% Load im Kernel (4 von 12 Threads) zeigt mir mpstat 1 1 jedenfalls folgendes:
Code:8:56:44 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle 08:56:45 AM all 1.16 0.00 34.75 0.00 0.00 0.00 0.00 0.00 64.09
Code:08:58:16 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle 08:58:17 AM all 16.60 46.46 32.36 0.00 0.00 0.17 0.00 0.00 4.42 Average: all 16.60 46.46 32.36 0.00 0.00 0.17 0.00 0.00 4.42
Code:$ top -d 00.01 -n1
Code:$ top -d 00.01 -n2
Code:$ top -d 00.01 -n5 | grep Cpu\(s\) Cpu(s): 0.9%us, 2.5%sy, 0.5%ni, 96.0%id, 0.1%wa, 0.0%hi, 0.0%si, 0.0%st Cpu(s): 4.2%us, 37.5%sy, 0.0%ni, 58.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu(s): 4.0%us, 40.0%sy, 0.0%ni, 56.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu(s): 4.2%us, 33.3%sy, 0.0%ni, 62.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu(s): 0.0%us, 39.1%sy, 0.0%ni, 60.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Dass du bei so kurzen Beobachtungszeitraeumen nur Werte rauskriegst, die scheinbar keinen Sinn ergeben, ist nur logisch und eine Folge aus der Art und Weise, wie das Accounting dieser Werte kernelseitig funktioniert: Linux fuehrt immer nur Absolutwerte fuer z. B. "time-slices on-CPU" (und diesen Wert z. B. auch noch in Abhaengigkeit der Tickrate des Schedulers) per PID, und das Berechnen von Werten wie "relative Auslastung der CPU durch PIDn", oder auch "Reads/s" oder "Writes/s" fuer Block-I/O-Statistiken, muss man aus diesen periodisch manifestierten Werten "haendisch" errechnen.
Wenn du dir Tools wie iostat anschaust:
Code:Linux 4.6.0-0.bpo.1-amd64 (redacted) 09/13/2016 _x86_64_ (56 CPU) Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util nvme0n1 0.06 2.57 451.64 659.19 3.94 41.96 84.63 4.30 3.87 0.21 6.38 0.07 7.43 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util nvme0n1 0.00 0.00 250.00 5.00 0.99 0.01 8.00 0.03 0.13 0.11 0.80 0.13 3.20 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util nvme0n1 0.00 0.00 243.00 4.00 0.96 0.01 8.05 0.03 0.11 0.12 0.00 0.11 2.80
Ok, alles klar. Habe dazu auch noch etwas nachgelesen und alles was ich finden konnte waren eben ähnliche Aussagen, daß man also einen Beobachtungszeitraum braucht.
Für's erste schaut meine Lösung jetzt Mal so aus (Zurückgegriffen auf bc, weil bash kann scheints keine Floats?), benutzt habe ich dennoch top, weil's schneller ist als mpstat:
Schaut perfekt aus? Scheint jedenfalls genau das zu tun was ich will, auch wenn "etwas zackiger" ganz nett wäre.Code:$ read -r -a loadarray <<< `top -d 00.01 -n2 | grep Cpu\\(s\\) | head -2 | tail -1` \\ && cpuload=0 && for i in {1,2,3,5,6,7,8}; do cpuload=$(echo $cpuload + `echo \\ "${loadarray[$i]}" | cut -d'%' -f1` | bc); done && echo -ne "$cpuload%" && unset \\ cpuload loadarray 34.8%
Bourne Shell kann nur Ganzzahlarithmetik, ja.
Die Ausgabe von top ist nicht stabil ueber Versionen hinweg und explizit nicht dazu da, sie maschinell zu parsen. Das Script wird dir also spaetestens beim naechsten Dist-Upgrade explodieren. In meiner Version sind die Felder "1,2,3,5,6,7,8", die du da referenzierst, mit tw. nichtnumerischen Werten belegt. Auszerdem faellt dir das alles auseinander, sobald bald ein Wert dreistellig vor dem Komma (100.0) wird, weil dann das Word Splitting beim `read´-Input versagt. Summa summarum: so wuerde ich das nicht implementieren.
Was genau ist jetzt eigentlich das Ziel? Du willst die non-Idle-Time all deiner CPUs in den letzten 0.01 Sekunden wissen?
Die 100% schaffe ich nicht, ich hab's probiert, aber irgendwas is einfach immer, was das zu verhindern scheint. Ich krieg z.B. nie 0.0%sy hin. 100.0%sy aber auch ned. Und was die Portabilität angeht: Mir wurscht. Distros upgrade ich vielleicht alle 8-10 Jahre, aber nicht öfter (CentOS). Und is ja ned so, daß man keine Delimiter oder Feldnummern ändern könnte auf die Schnelle. Das dauert eine Minute und passt.
Und mein Ziel: Ich will die reale, gesamte CPU Auslastung zu einem bestimmten Zeitpunkt in % messen, wobei "alle Threads unter Volllast" = 100%.
Und den ermittelten Wert will ich dann hinschupfen können, wo ich ihn haben will.
Wenn das eleganter geht, dann bitte nur her damit!
Auf modernen CPUs mit superfancy Powermanagement, verschiedensten Turbo-States usw. ist die "CPU-Auslastung" sowieso eine Kennzahl, die sehr kiritsch zu beaeugen und zu hinterfragen ist, und ggf. nicht mehr viel mit der tatsaechlichen Auslastung der Rechenwerke zu tun hat. Fuer Intel-CPUs kann man sich da mit i7z behelfen; das wird allerdings nicht mehr gepflegt und kann damit ggf. fuer Skylake und Co. keine zuverlaessigen Angaben mehr treffen. Wenn man sich sonst ueber die CPU-Charakteristika einer Workload informieren moechte, macht man das am besten mit perf.
Damit du irgendeine nette Zahl hast, die du anschauen kannst zum Sichgutfuehlen, wuerde ich das so angehen:
Code:read -r _{1..12} us sy id wa st < <(vmstat -nw 1 2 | tail -n1); printf '%d%%\\n' "$(($us+$sy))"
Hmm, auf andere Linuxversionen / -distros portabler Code is natürlich besser, schon klar.
Ich wollte einfach schnell sehen, ob was frei ist auf der CPU. Wenn ich z.B. "70%" sehe, kann ich mir sicher sein, daß es Reserven gibt, und daß ich einen Rechenjob nachschieben kann (ich mache selbiges auch mit'm RAM, aber in absoluten Zahlen statt %).
Wenn größere Jobs durch sind, krieg ich zwar auch Notifications, aber ich weiß nie was grade alles läuft auf der Kiste, und so seh ich halt schnell Mal ob was frei ist. Ich könnt's auch hinten ans Notify ankleben, um zu sehen ob nach Ende eines großen Jobs immer noch Load auf der Maschine war...
Klar geht das sicher alles irgendwie anders auch, aber wenn ich Mal etwas will, kann ich einfach keine Ruhe geben, auch wenn's nichts wirklich wichtiges/nützliches ist.
Lässig wär's jetzt nur noch, wenn das richtig schnell gehen würd (vmstat braucht auch eine Sekunde, schneller kann es nicht). Auf FreeBSD komm ich z.B. per folgendem sauflott an die Werte für alle Cores, hier beispielhaft mit einem AMD 8-Kerner unter voller Last (load avg ist grade knapp unter 17):
Also da spür ich GAR keine Wartezeit, da kann ich mir das fertige Teil auch in die ~/.bash_profile schmeißen und es stört nicht Mal beim Login... Execution Time 2ms! Das wär jetzt noch das Sahnehäubchen, wenn ich das unter Linux auch in sagen wir <100ms machen könnte, anstatt in 1sec mit vmstat oder ~500ms mit top (k.A. warum der 500ms+ wegfrisst bei "time top -d 00.01 -n2")...Code:$ sysctl dev.cpu | grep cx_usage dev.cpu.7.cx_usage: 100.00% 0.00% last 4967us dev.cpu.6.cx_usage: 100.00% 0.00% last 6037us dev.cpu.5.cx_usage: 100.00% 0.00% last 2685us dev.cpu.4.cx_usage: 100.00% 0.00% last 6968us dev.cpu.3.cx_usage: 100.00% 0.00% last 4906us dev.cpu.2.cx_usage: 100.00% 0.00% last 5830us dev.cpu.1.cx_usage: 100.00% 0.00% last 7376us dev.cpu.0.cx_usage: 100.00% 0.00% last 2973us
mit recode kannst du die htop Ausgabe "lesbar" machen. Ein Batch Mode ist schon länger als FR drin, hat sich aber noch nix getan.
htop | recode utf-8 > bla.txt
Ah.. Danke. Auf der Basis sollte ich mir was bauen können, htop mit -d1 starten, für 1-2 Zehntelsekunden am Leben lassen (je nachdem wie lange es braucht um ordentliche Daten zu erhalten), dann killen, die Daten filzen und passt.
Mh!
Werd ich (wenn Zeit ist) morgen Mal ausprobieren, zwecks der Gaudi!
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2024