bisher war ich der Meinung, bei einer Load >1 sollte die CPU zu 100%
ausgelastet sein. Bei mir war es aber gerade so, daß die CPU nichts
tut und die Load bei fünf steht. An was kann das liegen und wie
krieg ich das weg? Nachdem ich das System neu gestartet habe ist
im Moment alles normal.
Top meinte:
top - 15:48:00 up 1 day, 1:24, 2 users, load average: 5.19, 4.70, 3.44
Tasks: 101 total, 2 running, 99 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.0% us, 2.0% sy, 0.0% ni, 96.4% id, 0.0% wa, 0.7% hi, 0.0% si
Mem: 515948k total, 472792k used, 43156k free, 14280k buffers
Swap: 1461872k total, 103344k used, 1358528k free, 215552k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4489 root 5 -10 107m 27m 2248 S 1.3 5.4 40:02.12 Xorg
4 root 10 -5 0 0 0 S 1.0 0.0 15:22.23 events/0
12908 wolfgang 15 0 3828 1852 1584 S 0.3 0.4 0:07.93 xosview
13670 wolfgang 16 0 2196 1116 848 R 0.3 0.2 0:00.58 top
1 root 16 0 1880 288 256 S 0.0 0.1 0:00.41 init
2 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
5 root 13 -5 0 0 0 S 0.0 0.0 0:00.02 khelper
6 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 kthread
8 root 20 -5 0 0 0 S 0.0 0.0 0:00.00 kacpid
Welche weiteren Informationsquellen sollte ich, falls das Problem wieder
auftritt, noch sichern um den Übeltäter zu finden? Ich verwende
Debian testing mit einem selbstgebauten Kernel:
Linux greg 2.6.14 #1 PREEMPT Mon Dec 12 03:18:05 CET 2005 i686 GNU/Linux
Tschüß,
Wolfgang
--
Wolfgang Becker *** eMail ua...@gmx.de *** http://uafr.freeshell.org/
Bei Linux heisst Load > 1 nicht unbedingt 100% CPU. Da wird z.B. auch
I/O reingerechnet. Wenn man also gerade auf (langsamen) Laufwerken
rumroedelt oder aufgrund eines Sektorfehlers einer Platte der
Kernel-I/O-Code beschaeftigt ist geht die Load auch hoch. 0% CPU bei
Load bis zu 8 hatte ich auch schon, die 0% waren da dann aber vermutlich
gelogen. Selbst wenns gestimmt hat und der Kernel auf irgenwas gewartet
hat, standen die - angeblich freien - 100% CPU jedenfalls nicht dem
Userspace zur Verfuegung.
Micha
P.S.: Waren bei mir allerdings alles aeltere Kernels < 2.6
--
HTML mails are rejected
Vielleicht ein Prozess im "uninterruptable sleep"? Hast du von dem Load
was gemerkt?
> Nachdem ich das System neu gestartet habe ist im Moment alles normal.
Das wäre in dem Fall plausibel.
Falls es nochmal auftritt, achte mal drauf, ob du in der Prozessliste
bei einem oder mehreren Prozessen unter STAT ein "D" findest.
gruß,
--
Lutz Frommberger | "Wenn ist das Nunstück git und
| Slotermeyer? Ja! ... Beiherhund
http://www.aussagekraft.de | das Oder die Flipperwaldt
pgp key on request | gersput." - Ernest Scribbler
Lutz Frommberger wrote:
>>bisher war ich der Meinung, bei einer Load >1 sollte die CPU zu 100%
>>ausgelastet sein. Bei mir war es aber gerade so, daß die CPU nichts
>>tut und die Load bei fünf steht. An was kann das liegen und wie
>>krieg ich das weg?
>
>
> Vielleicht ein Prozess im "uninterruptable sleep"? Hast du von dem Load
> was gemerkt?
Wozu moegen eigentlich diese d state Prozesse gut sein? O.K. ich
weiss schon, was das ist. Deshalb sehe ich trotzdem nicht ein,
warum man die mit einem geeigneten Signal von kill nicht terminieren
kann.
Rainer Haessner
"Gerechnet" wird da eigentlich gar nicht viel: der Load ist doch nur
die durchschnittliche Länge der Prozesswarteschlange (plus laufenden
Prozessen, denke ich mal). Oder lieg ich da total falsch?
Es ist halt nicht nur freie CPU-Kapazität, auf die ein Prozess warten
kann.
Ja, das System wurde träge, manche Programme haben extrem lange zum
Starten gebraucht.
> Falls es nochmal auftritt, achte mal drauf, ob du in der Prozessliste
> bei einem oder mehreren Prozessen unter STAT ein "D" findest.
Nachdem das gerade nochmal war hab ich nachgeschaut, war aber keiner
dabei. Die "was hab ich zuletzt geändert"-Frage hat mich darauf
gebracht, daß HAL der Schuldige sein könnte. Gnome wollte die
"Hardware Abstraction Layer" haben. Mal schauen ob das Problem ohne
hald nochmal auftritt.
Wolfgang Becker wrote:
>>Vielleicht ein Prozess im "uninterruptable sleep"? Hast du von dem Load
>>was gemerkt?
>
>
> Ja, das System wurde träge, manche Programme haben extrem lange zum
> Starten gebraucht.
>
>
>>Falls es nochmal auftritt, achte mal drauf, ob du in der Prozessliste
>>bei einem oder mehreren Prozessen unter STAT ein "D" findest.
>
>
> Nachdem das gerade nochmal war hab ich nachgeschaut, war aber keiner
> dabei. Die "was hab ich zuletzt geändert"-Frage hat mich darauf
> gebracht, daß HAL der Schuldige sein könnte. Gnome wollte die
> "Hardware Abstraction Layer" haben. Mal schauen ob das Problem ohne
> hald nochmal auftritt.
beagle?
Macht zumindest mir derzeit recht viel Aerger.
Kann man leicht mir
ps -ef | grep mono
herausfinden.
Rainer Haessner
Nein. Die Load gibt an, wieviele Prozesse, gemittelt über eine bestimmte
Zeitspanne (1, 5 und 15 Minuten), Prozessorzeit haben wollen.
Wenn also z.B. 10 Prozesse 6 Sekunden lang ständig Prozessorzeit wollen,
hast du auch eine Load 1, obwohl die CPU sich 54 Sekunden lange
langweilt.
> Bei mir war es aber gerade so, daß die CPU nichts
> tut und die Load bei fünf steht. An was kann das liegen und wie
Vermutlich wollten kurzzeitig sehr viele Prozesse CPU-Zeit.
> krieg ich das weg?
Abwarten.
> Welche weiteren Informationsquellen sollte ich, falls das Problem wieder
> auftritt, noch sichern um den Übeltäter zu finden? Ich verwende
ps ar zeigt die die derzeit laufenden Prozesse
Florian
--
Einen Troll zu füttern ist das gleiche als würde man einen Haufen
Hundescheisse sehen, absichtlich reinsteigen und sich dann beschweren.
(Christian Schneider in <2005-10-2...@bofh.my-fqdn.de>)
Weil die Hardware, mit der der Prozess gerade kommuniziert, dann in
möglicherweise einem undefinierten Zustand wäre.
Sowas hab ich nicht. Zumindest nicht vorsätzlich installiert. :)
> Kann man leicht mir
> ps -ef | grep mono
> herausfinden.
wolfgang@greg:~$ ps -ef | grep mono
wolfgang 4668 4653 0 20:13 ? 00:00:27 mono /usr/lib/GreenT/GreenT.exe
wolfgang 5444 5342 0 23:26 pts/2 00:00:00 grep mono
Nein, kein beagle, nur das Terminal.
Ack. Was ich meinte ist, dass Linux offenbar auch irgendwelche internen
Kernelaktivitaeten bei der Load mitzaehlt (und nicht nur die sichtbaren
Prozesse). Wie kommen sonst
a)
solche Load-Werte zustande obwohl die Anzahl der sichtbaren Prozesse die
die CPU haben wollen <Load ist?
Und
b)
Wenn die CPU wirklich nichts zu tun haette, warum kriegen sie die
wartenden Prozesse dann nicht?
=> Die Load-Werte beziehen sich also offenbar auf Prozesse+Kernel, die
CPU-Werte aber nur auf die Prozesse.
Micha
> Ack. Was ich meinte ist, dass Linux offenbar auch irgendwelche internen
> Kernelaktivitaeten bei der Load mitzaehlt (und nicht nur die sichtbaren
> Prozesse). Wie kommen sonst
> a)
> solche Load-Werte zustande obwohl die Anzahl der sichtbaren Prozesse die
> die CPU haben wollen <Load ist?
Ist das auch im Mittel so? Die Load Werte sind ja gemittelt und spiegeln
nicht die aktuellen Messungen. Durch die expotentielle Glaettung kann
das 'Abklingen' sich etwas verzoegern. Kann man es damit vielleicht
erklaeren?
> Wenn die CPU wirklich nichts zu tun haette, warum kriegen sie die
> wartenden Prozesse dann nicht?
Hmm, also eine CPU wird einen 'Prozess' fuer eine kurze Zeit rechnen
lassen und die anderen werden auf die Zuweisung warten. Hat die CPU
wirklich nichts zu tun?
>=> Die Load-Werte beziehen sich also offenbar auf Prozesse+Kernel, die
> CPU-Werte aber nur auf die Prozesse.
Also hierfuer habe ich keine Hinweise gefunden. Ich habe mir mal ein
wenig die relevanten Stellen im Kernel Code angesehen:
linux-2.6.15/kernel/timer.c:
/*
* calc_load - given tick count, update the avenrun load estimates.
* This is called while holding a write_lock on xtime_lock.
*/
static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
count -= ticks;
if (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}
Mit calc_load werden also die drei Werte aktualisiert. LOAD_FREQ ist das
Intervall der aequidistanten Abtastungen (hier 5 sek., siehe weiter unten).
Daher sollte 5 - ticks (Ticks entspricht der Linuxsystemzeit seit dem
Systemstart. Gemessen wird in Einheiten zu je 10 ms) auch < 0 sein.
Andernfalls waere das System scheinbar erst seit 0..49 ms up, da waere
der Durchschnitt wohl nicht notwendig.
Die Anzahl der Prozesse kommt nun mit count_active_tasks() ins Spiel.
Diese Prozedur ist in timer.c definiert als:
/*
* Nr of active tasks - counted in fixed-point numbers
*/
static unsigned long count_active_tasks(void)
{
return (nr_running() + nr_uninterruptible()) * FIXED_1;
}
nr_running bezieht sich dabei scheinbar auf die Angabe nr_running in
der runqueue Struktur, die in linux-2.6.15/kernel/sched.c definiert
ist. Das ist also die Anzahl der Prozesse in der Runqueue. In der
Runqueue befinden sich Prozesse mit dem Zustand TASK_RUNNING. Diese
sind entweder schon einer CPU zugeteilt (und verbrauchen dementsprechend
Rechenzeit), oder warten auf Zuweisung zu einer CPU durch den Scheduler.
Prozesse im Zustand TASK_UNITERRUPTIBLE warten auf ein Ereignis, koenne
aber im Gegensatz zu denen im Zustand TASK_INTERRUPTIBLE (die sich in
der waitqueue befinden) nicht durch ein Signal aufgeweckt werden.
Der letzte Schritt ist nun das Macro CALC_LOAD. Dieses ist hier
definiert:
linux-2.6.15/include/linux/sched.h:
#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;
Ueber das Macro wird nun der neue Load werd berechnet. Dabei ist load
der Load zur letzten Messung, exp ein Faktor zur Glaettung und n die
Anzahl der laufenden Prozesse (siehe oben).
Etwas anders dargestellt, sieht die Funktion so aus:
load(t) = load(t-1) * exp + n(t)*(1-exp)
load(t-1) = Load zur letzten Messung
load(t) = aktuelle Load
n(t) = aktuell laufende Prozesse
exp ist ein Faktor zur Glaettung. exp := e^(-(5/60m)), wobei m der
Zeitraum der Messung ist, also m ist in {1,5,15}. Dadurch wird das
Aussehen der Expotentialfunktion veraendert und damit auch die
Glaettung. Somit kommt man auch auf die Konstanten EXP_i.
Zum Beispiel ist EXP_1 = 2^FSHIFT * e^(-(5/60)).
(Diese Glaettung ist mir aus der Literatur als expotential smoothing
bekannt)
Soweit mein Verstaednis davon. Also, hier gehen wirklich nur die
Prozesse ein und keine anderen Kernelinternas.
Gruss,
Oliver
--
Oliver Hohlfeld <|> DO1FDK <|> http://www.ohohlfeld.com
Linux user #191885
Ja.
> Die Load Werte sind ja gemittelt und spiegeln
> nicht die aktuellen Messungen. Durch die expotentielle Glaettung kann
> das 'Abklingen' sich etwas verzoegern. Kann man es damit vielleicht
> erklaeren?
Ich habe gerade mal so ein Szenario nachgestellt (im Hintergrund aufs MO
schreiben, ca. 25 Minuten). Was ich die ganze Zeit gesehen habe ist folgendes:
-------------------------------------------------------------------------------
[micha@WStation1:/home/micha]> top
2:24am up 25 min, 6 users, load average: 4.14, 3.84, 2.31
74 processes: 73 sleeping, 1 running, 0 zombie, 0 stopped
CPU states: 2.5% user, 8.0% system, 0.0% nice, 90.0% idle
Mem: 176732K av, 173600K used, 3132K free, 57696K shrd, 102796K buff
Swap: 136512K av, 0K used, 136512K free 19448K cached
PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND
308 micha 17 0 1204 1204 996 S 0 3.5 0.6 1:17 xosview.bin
419 micha 9 0 792 792 612 R 0 2.1 0.4 0:13 top
2 root 6 0 0 0 0 DW 0 1.3 0.0 0:12 kflushd
3 root 6 0 0 0 0 DW 0 0.9 0.0 0:11 kupdate
398 micha 2 0 1956 1956 1444 S 0 0.7 1.1 0:04 xterm
293 root 2 0 11784 11M 2080 S 0 0.1 6.6 0:44 X
[...]
-------------------------------------------------------------------------------
Die Load ueber ca. 25min sah graphisch so aus:
http://micha.freeshell.org/tmp/load.gif
Also Load ca. 4, CPU ca. 10% aber Prozesse mit R-Flag 0 (der eine war quasi
immer das top selbst). Offensichtlich wird auch alles was ein D-Flag hat - also
auf den Kern wartet - zur Load dazugerechnet (was ich falsch finde), sonst kommt
man niemals auf 4.
> > Wenn die CPU wirklich nichts zu tun haette, warum kriegen sie die
> > wartenden Prozesse dann nicht?
War Bloedsinn. Sie wuerden sie kriegen, aber da will keiner. Hatte ich irgendwie
falsch in Erinnerung.
> Hmm, also eine CPU wird einen 'Prozess' fuer eine kurze Zeit rechnen
> lassen und die anderen werden auf die Zuweisung warten. Hat die CPU
> wirklich nichts zu tun?
Ja, sie hat tatsaechlich nichts zu tun (genauer: beide haben nicht viel zu tun,
jede ca. 5% - ist eine SMP Maschine).
Die Frage ist also, wo dann die Load von 4 herkommt wenn doch alles nur wartet
und niemand die CPUs benutzt bzw. benutzen will ...
> >=> Die Load-Werte beziehen sich also offenbar auf Prozesse+Kernel, die
> > CPU-Werte aber nur auf die Prozesse.
>
> Also hierfuer habe ich keine Hinweise gefunden. Ich habe mir mal ein
> wenig die relevanten Stellen im Kernel Code angesehen:
> [...]
>
> Etwas anders dargestellt, sieht die Funktion so aus:
>
> load(t) = load(t-1) * exp + n(t)*(1-exp)
>
> load(t-1) = Load zur letzten Messung
> load(t) = aktuelle Load
> n(t) = aktuell laufende Prozesse
>
> exp ist ein Faktor zur Glaettung. exp := e^(-(5/60m)), wobei m der
> Zeitraum der Messung ist, also m ist in {1,5,15}. Dadurch wird das
> Aussehen der Expotentialfunktion veraendert und damit auch die
> Glaettung. Somit kommt man auch auf die Konstanten EXP_i.
> Zum Beispiel ist EXP_1 = 2^FSHIFT * e^(-(5/60)).
> (Diese Glaettung ist mir aus der Literatur als expotential smoothing
> bekannt)
Ja, speziell dass die Load niemals schlagartig sinkt sieht man auch auf meiner
Graphik (Link oben).
> Soweit mein Verstaednis davon. Also, hier gehen wirklich nur die
> Prozesse ein und keine anderen Kernelinternas.
Hmm, obiger Versuch war mit einem 2.2.26 Kernel, da koennte sich bis 2.6.15 ja
diverses veraendert haben. Ich versuche das mal bei Gelegenheit zu analysieren,
jetzt bin ich zu muede dazu ...
Micha
--
Wenn etwas einfach aussieht, hat man es nicht verstanden
Ja, top läuft natürlich immer gerade, wenn es was ausgibt - das verzerrt
die Ausgabe.
> Offensichtlich wird auch alles was ein D-Flag hat - also auf den Kern
> wartet - zur Load dazugerechnet (was ich falsch finde), sonst kommt
> man niemals auf 4.
So ist es. Load ist
Anzahl der laufenden Prozesse
+ Anzahl der Prozesse, die auf CPU warten
+ Anzahl der Prozesse im Uninterruptible Wait (aka. "Disk Wait")
Ob das nun richtig oder falsch ist, darüber kann man streiten. Es ist
jedenfalls "richtiger" als nur die Prozesse zu zählen, die auf die CPU
warten. Hard Disks sind weit öfter ein Bottleneck als die CPU und auch
"grobkörniger" im Scheduling: Ein paar tausend Context Switches pro
Sekunde schafft jede CPU spielend - aber wenn eine Disk einen Seek ans
andere Ende der Platte macht, dann ist sie erst mal ein paar
Millisekunden beschäftigt und kann nichts anderes machen[1]. D.h. subjektiv
fühlt sich das System wesentlich träger an, wenn ein Prozess die Hard
Disk ordentlich prügelt, als wenn ein Prozess dauernd CPU-Zeit frisst.
Natürlich wird eine einzelne Zahl immer unaussagekräftiger, je mehr
Devices man da reinmischt: Wenn ich 4 CPUs, 20 Disks und 5 Bandlaufwerke
habe, dann sagt mir eine Load von 10 fast gar nichts mehr: Das kann
heißen, dass da von 5 Disks auf 5 Bänder kopiert wird und wenn ich nicht
gerade versuche, auf die 5 Disks zuzugreifen, läuft alles mit voller
Geschwindigkeit, oder es kann heißen, dass das ganze System recht gut
ausgelastet ist.
hp
[1] Ja, Tagged Queuing hilft da ein bisschen.
--
This is not a signature
Dann tun wir das doch mal ... ;-)
> Es ist
> jedenfalls "richtiger" als nur die Prozesse zu zählen, die auf die CPU
> warten.
Finde ich nicht, dann wuerdet die Zahl wenigstens was aussagen. So ganz
grob: Wenn die Load die Zahl der CPUs ueberschreitet ist die Maschine
(von der Rechenpower her) ausgelastet. Im obigen Beispiel ist der Wert
fast zur Hausnummer verwaessert worden.
> Hard Disks sind weit öfter ein Bottleneck als die CPU und auch
> "grobkörniger" im Scheduling: Ein paar tausend Context Switches pro
> Sekunde schafft jede CPU spielend -
Dann wuerde ja jeder Task immer nur ein paar Mikrosekunden (am Stueck)
laufen. Ich dachte, dass da einige Milisekunden ueblich sind.
> aber wenn eine Disk einen Seek ans
> andere Ende der Platte macht, dann ist sie erst mal ein paar
> Millisekunden beschäftigt und kann nichts anderes machen[1].
Der Cache der Platte kann unter Umstaenden auch wahrend eines Seeks
einen Zugriff des Hosts befriedigen.
> D.h. subjektiv
> fühlt sich das System wesentlich träger an, wenn ein Prozess die Hard
> Disk ordentlich prügelt, als wenn ein Prozess dauernd CPU-Zeit frisst.
> Natürlich wird eine einzelne Zahl immer unaussagekräftiger, je mehr
> Devices man da reinmischt: Wenn ich 4 CPUs, 20 Disks und 5 Bandlaufwerke
> habe, dann sagt mir eine Load von 10 fast gar nichts mehr: [...]
Es sollte halt schon irgendwie zusammenpassen: In meinem Beispiel
kopiert _ein_ Prozess auf _ein_ MO und erzeugt dabei eine Load von 4
obwohl der Vorgang ausser dem MO-Laufwerk selbst weder die CPUs noch die
I/O-Ressourcen (Busse, andere Laufwerke) signifikant belastet. Das
System als ganzes ist also alles aber nicht "ausgelastet". Ich finde
eine Load von 4 repraesentiert den Zustand des Systems hier nicht
angemessen - verglichen mit sechs R-Tasks die kein I/O machen aber die
gleiche Load erzeugen wuerden, das wuerde sich anders anfuehlen.
> [1] Ja, Tagged Queuing hilft da ein bisschen.
Bin dabei :)
>
>>Es ist
>>jedenfalls "richtiger" als nur die Prozesse zu zählen, die auf die CPU
>>warten.
>
> Finde ich nicht, dann wuerdet die Zahl wenigstens was aussagen. So ganz
> grob: Wenn die Load die Zahl der CPUs ueberschreitet ist die Maschine
> (von der Rechenpower her) ausgelastet.
Wenn 30 Prozesse auf die Festplatte warten, ist die Maschine auch
ausgelastet.
> Im obigen Beispiel ist der Wert
> fast zur Hausnummer verwaessert worden.
>
>>Hard Disks sind weit öfter ein Bottleneck als die CPU und auch
>>"grobkörniger" im Scheduling: Ein paar tausend Context Switches pro
>>Sekunde schafft jede CPU spielend -
>
> Dann wuerde ja jeder Task immer nur ein paar Mikrosekunden (am Stueck)
> laufen. Ich dachte, dass da einige Milisekunden ueblich sind.
Linux hat aktuell eine Defaul-Timeslice von 4ms (zwischendurch mal 1ms).
Aber wenn der Prozess z.B. auf die Festplatte warten muss, ist natürlich
der nächste dran.
>
>>aber wenn eine Disk einen Seek ans
>>andere Ende der Platte macht, dann ist sie erst mal ein paar
>>Millisekunden beschäftigt und kann nichts anderes machen[1].
>
> Der Cache der Platte kann unter Umstaenden auch wahrend eines Seeks
> einen Zugriff des Hosts befriedigen.
Bei ATA? Fußnote nicht vergessen.
>
>>D.h. subjektiv
>>fühlt sich das System wesentlich träger an, wenn ein Prozess die Hard
>>Disk ordentlich prügelt, als wenn ein Prozess dauernd CPU-Zeit frisst.
>>Natürlich wird eine einzelne Zahl immer unaussagekräftiger, je mehr
>>Devices man da reinmischt: Wenn ich 4 CPUs, 20 Disks und 5 Bandlaufwerke
>>habe, dann sagt mir eine Load von 10 fast gar nichts mehr: [...]
>
> Es sollte halt schon irgendwie zusammenpassen: In meinem Beispiel
> kopiert _ein_ Prozess auf _ein_ MO und erzeugt dabei eine Load von 4
> obwohl der Vorgang ausser dem MO-Laufwerk selbst weder die CPUs noch die
> I/O-Ressourcen (Busse, andere Laufwerke) signifikant belastet.
Da läuft in der Tat was falsch. Solltest Du falls möglich genauer
untersuchen.
>>[1] Ja, Tagged Queuing hilft da ein bisschen.
> Micha
--
Gruß,
Sebastian
Ja, aber nichts besonders interessantes.
Ich kenne das von BSD (vor 15 Jahren): Da sinkt die Load, wenn das
System wirklich ausgelastet ist, weil die Prozesse gar nicht mehr in den
Zustand kommen, wo sie CPU-Zeit brauchen könnten, und somit in der
Load-Average nicht mehr mitgezählt werden.
> So ganz grob: Wenn die Load die Zahl der CPUs ueberschreitet ist die
> Maschine (von der Rechenpower her) ausgelastet.
Nein, nicht wirklich. Es sagt nicht mal aus, dass die CPU 100% der Zeit
sinnvolles tut: Es könnten z.B. zu jeder vollen Sekunde 10 Prozesse
gestartet werden, die jeweils 50 ms CPU-Zeit brauchen. Dann hat die CPU
jeweils eine halbe Sekunde was zu tun und eine halbe Sekunde nichts zu
tun, die Load wäre aber 5 (10 * 0.5 + 0 * 0.5).
Und als Maß für die Belastung des "Gesamtsystems" taugt die Belastung
der CPU(s) alleine nicht viel - die CPU ist nur relativ selten das
Bottleneck (mag vielleicht bei Leuten, die gleichzeitig gamen,
Videoschneiden und Seti@home-Rekorde brechen wollen, anders sein).
> Im obigen Beispiel ist der Wert fast zur Hausnummer verwaessert
> worden.
Finde ich nicht. "Anzahl der Prozesse, die auf eine zeitkritische
Resource warten" ist i.A. deutlich aussagekräftiger als "Anzahl der
Prozesse, die auf die CPU warten". Es stimmt natürlich, das
"uninterruptible wait" nicht immer mit "zeitkritische Resource"
übereinstimmt.
Hausnummern sind beides. Die Anzahl der Prozesse in der Run-Queue ist
nur noch unbrauchbarer als das, was SysV-Unixe (inkl. Linux) als Load
Average ausgeben.
> > Hard Disks sind weit öfter ein Bottleneck als die CPU und auch
> > "grobkörniger" im Scheduling: Ein paar tausend Context Switches pro
> > Sekunde schafft jede CPU spielend -
>
> Dann wuerde ja jeder Task immer nur ein paar Mikrosekunden (am Stueck)
> laufen. Ich dachte, dass da einige Milisekunden ueblich sind.
>
Prozesse können nicht nur am Ende einer Timeslice unterbrochen werden.
Wenn ein Prozess mit höherer Priorität lauffähig wird (z.B. weil die die
Disk gerade den Sektor geliefert hat, den er lesen wollte), dann wird
ein eventuell gerade laufender niedrigerpriorisierter Prozess
unterbrochen. Auf Systemen, wo mehrere Prozesse hauptsächlich I/O-bound
sind (Datenbankserver, Fileserver, Webserver) sind ein paar tausend
Context-Switches pro Sekunde tatsächlich nichts besonderes.
Ich habe gerade mal vmstat auf unserem Fileserver (derzeit 64 User) ein
paar Sekunden mitlaufen lassen:
vvvv
0 1 0 37488 95848 201380 521148 0 0 368 0 603 671 1 1 98
1 0 0 37488 94456 201688 522176 0 0 304 0 5651 5538 3 2 95
6 0 1 37488 90216 201744 522416 0 0 4 704 6374 3439 43 10 47
0 0 0 37488 90252 201776 522620 0 0 12 336 5482 2961 16 8 77
procs memory swap io system cpu
r b w swpd free buff cache si so bi bo in cs us sy id
0 0 0 37488 90252 201844 522832 0 0 0 3352 5311 4688 4 4 92
0 0 0 37488 90416 201844 522836 0 0 0 0 199 91 0 0 99
0 0 0 37488 90416 201844 522836 0 0 0 0 175 78 1 0 99
^^^^
> > aber wenn eine Disk einen Seek ans
> > andere Ende der Platte macht, dann ist sie erst mal ein paar
> > Millisekunden beschäftigt und kann nichts anderes machen[1].
>
> Der Cache der Platte kann unter Umstaenden auch wahrend eines Seeks
> einen Zugriff des Hosts befriedigen.
Ja, wenn's im Cache ist. Dann ist es aber bei Linux mit einiger
Wahrscheinlichkeit eh auch im Cache des Betriebssystems und das
Betriebssystem fragt die Platte gar nicht erst :-).
Benötigt aber auch Tagged Queueing (wie in meiner Fußnote angemerkt),
also SCSI oder SATA und eine Platte die das beherrscht (dass es der
Treiber kann, davon gehe ich mal aus).
> > D.h. subjektiv fühlt sich das System wesentlich träger an, wenn ein
> > Prozess die Hard Disk ordentlich prügelt, als wenn ein Prozess
> > dauernd CPU-Zeit frisst. Natürlich wird eine einzelne Zahl immer
> > unaussagekräftiger, je mehr Devices man da reinmischt: Wenn ich 4
> > CPUs, 20 Disks und 5 Bandlaufwerke habe, dann sagt mir eine Load von
> > 10 fast gar nichts mehr: [...]
>
> Es sollte halt schon irgendwie zusammenpassen: In meinem Beispiel
> kopiert _ein_ Prozess auf _ein_ MO und erzeugt dabei eine Load von 4
> obwohl der Vorgang ausser dem MO-Laufwerk selbst weder die CPUs noch die
> I/O-Ressourcen (Busse, andere Laufwerke) signifikant belastet.
Ja, die Load steigt beim Zugriff auf ATA-Devices stärker als man
vermuten würde. Allerdings fühlt sich das System auch tatsächlich zäh
an - da werden offenbar auch Prozesse blockiert, die nicht auf das MO
zugreifen, und das merkt man sowohl beim Arbeiten als auch an der Load.
Ich schätze, am ATA-Treiber könnte man noch was verbessern :-).
> Das System als ganzes ist also alles aber nicht "ausgelastet". Ich
> finde eine Load von 4 repraesentiert den Zustand des Systems hier
> nicht angemessen - verglichen mit sechs R-Tasks die kein I/O machen
> aber die gleiche Load erzeugen wuerden, das wuerde sich anders
> anfuehlen.
6 Tasks, die nur CPU-Zeit brauchen, merke ich beim normalen Arbeiten nur
daran, dass der Lüfter so laut ist (ja, auch auf dem 800 MHz-Notebook
hier) das fühlt sich nur leicht zäher an als ein unbelastetes System.
hp
Aber nur, wenn sie nur eine einzige Platte hat. In meinem Fall hat nur
das MO geroedelt, 3 weitere Platten (inklusive der Systemplatte) und
ausreichend Buskapazitaet sowohl auf dem SCSI als auch dem PCI lagen
brach. Zusammen mit 2 gelangweilten CPUs kann man da IMHO nicht von
"ausgelastet" sprechen.
> > Im obigen Beispiel ist der Wert
> > fast zur Hausnummer verwaessert worden.
> >
> > > Hard Disks sind weit öfter ein Bottleneck als die CPU und auch
> > > "grobkörniger" im Scheduling: Ein paar tausend Context Switches pro
> > > Sekunde schafft jede CPU spielend -
> >
> > Dann wuerde ja jeder Task immer nur ein paar Mikrosekunden (am Stueck)
> > laufen. Ich dachte, dass da einige Milisekunden ueblich sind.
>
> Linux hat aktuell eine Defaul-Timeslice von 4ms (zwischendurch mal 1ms).
> Aber wenn der Prozess z.B. auf die Festplatte warten muss, ist natürlich
> der nächste dran.
OK, ich hatte an Prozesse gedacht die alle was tun wollen. Anderenfalls
sind die Wechsel natuerlich schneller - Denkfehler meinerseits.
> > > aber wenn eine Disk einen Seek ans
> > > andere Ende der Platte macht, dann ist sie erst mal ein paar
> > > Millisekunden beschäftigt und kann nichts anderes machen[1].
> >
> > Der Cache der Platte kann unter Umstaenden auch wahrend eines Seeks
> > einen Zugriff des Hosts befriedigen.
>
> Bei ATA? Fußnote nicht vergessen.
Bei Schreibzugriffen und eingeschaltetem Write-cache wohl auch bei ATA.
Zugegeben, das will keiner haben. Sinnvoll nutzbar wohl nur mit
`Fussnote [1]`.
> > > D.h. subjektiv
> > > fühlt sich das System wesentlich träger an, wenn ein Prozess die Hard
> > > Disk ordentlich prügelt, als wenn ein Prozess dauernd CPU-Zeit frisst.
> > > Natürlich wird eine einzelne Zahl immer unaussagekräftiger, je mehr
> > > Devices man da reinmischt: Wenn ich 4 CPUs, 20 Disks und 5 Bandlaufwerke
> > > habe, dann sagt mir eine Load von 10 fast gar nichts mehr: [...]
> >
> > Es sollte halt schon irgendwie zusammenpassen: In meinem Beispiel
> > kopiert _ein_ Prozess auf _ein_ MO und erzeugt dabei eine Load von 4
> > obwohl der Vorgang ausser dem MO-Laufwerk selbst weder die CPUs noch die
> > I/O-Ressourcen (Busse, andere Laufwerke) signifikant belastet.
>
> Da läuft in der Tat was falsch. Solltest Du falls möglich genauer
> untersuchen.
Ich bitte um Geduld bis zum WE.
> > > [1] Ja, Tagged Queuing hilft da ein bisschen.
Micha
--
HTML mails are rejected
Wenn man um jeden Preis _eine_ Zahl haben will, dann muss man den
I/O-Part aber etwas sinnvoller reinbringen als mein System das tut. Ich
wuerde einen extra Wert fuer die I/O-Load bevorzugen. Wie man den dann
sinnvoll berechnen soll ist natuerlich nicht trivial.
> > So ganz grob: Wenn die Load die Zahl der CPUs ueberschreitet ist die
> > Maschine (von der Rechenpower her) ausgelastet.
>
> Nein, nicht wirklich. Es sagt nicht mal aus, dass die CPU 100% der Zeit
> sinnvolles tut: Es könnten z.B. zu jeder vollen Sekunde 10 Prozesse
> gestartet werden, die jeweils 50 ms CPU-Zeit brauchen. Dann hat die CPU
> jeweils eine halbe Sekunde was zu tun und eine halbe Sekunde nichts zu
> tun, die Load wäre aber 5 (10 * 0.5 + 0 * 0.5).
OK, das ist ein Argument.
Was die CPUs am Ende wirklich tun, weiss ich aber trotzdem - die
Belastung fuer jede CPU kriegt man ja als separaten Wert (xosview zeigt
alle drei ggf. auch nebeneinander an). Das ist prinzipiell alles gut so,
nur die I/O-Sachen haette ich lieber als extra Wert(e) und nicht im
Load-Wert mit drin.
> Und als Maß für die Belastung des "Gesamtsystems" taugt die Belastung
> der CPU(s) alleine nicht viel - die CPU ist nur relativ selten das
> Bottleneck (mag vielleicht bei Leuten, die gleichzeitig gamen,
> Videoschneiden und Seti@home-Rekorde brechen wollen, anders sein).
>
> > Im obigen Beispiel ist der Wert fast zur Hausnummer verwaessert
> > worden.
>
> Finde ich nicht. "Anzahl der Prozesse, die auf eine zeitkritische
> Resource warten" ist i.A. deutlich aussagekräftiger als "Anzahl der
> Prozesse, die auf die CPU warten". Es stimmt natürlich, das
> "uninterruptible wait" nicht immer mit "zeitkritische Resource"
> übereinstimmt.
>
> Hausnummern sind beides. Die Anzahl der Prozesse in der Run-Queue ist
> nur noch unbrauchbarer als das, was SysV-Unixe (inkl. Linux) als Load
> Average ausgeben.
Alleine schon, aber zusammen mit den anderen Werten koennte sich ein
guter Ueberblick ergeben.
> [Context Switches pro Sekunde]
War ein Denkfehler meinerseits, siehe anderes Posting.
> Ich habe gerade mal vmstat auf unserem Fileserver (derzeit 64 User) ein
> paar Sekunden mitlaufen lassen:
>
> vvvv
> 0 1 0 37488 95848 201380 521148 0 0 368 0 603 671 1 1 98
> 1 0 0 37488 94456 201688 522176 0 0 304 0 5651 5538 3 2 95
> 6 0 1 37488 90216 201744 522416 0 0 4 704 6374 3439 43 10 47
> 0 0 0 37488 90252 201776 522620 0 0 12 336 5482 2961 16 8 77
> procs memory swap io system cpu
> r b w swpd free buff cache si so bi bo in cs us sy id
> 0 0 0 37488 90252 201844 522832 0 0 0 3352 5311 4688 4 4 92
> 0 0 0 37488 90416 201844 522836 0 0 0 0 199 91 0 0 99
> 0 0 0 37488 90416 201844 522836 0 0 0 0 175 78 1 0 99
> ^^^^
[root@WStation4:/root]# man vmstat
There is not an entry for vmstat.
Sag mal bitte ein paar Takte dazu.
> [Seek => ein paar Millisekunden beschäftigt].
> >
> > Der Cache der Platte kann unter Umstaenden auch wahrend eines Seeks
> > einen Zugriff des Hosts befriedigen.
> [...]
Wie im anderen Posting gesagt mit Write-cache (und/oder TCQ)
> (dass es [TCQ] der Treiber kann, davon gehe ich mal aus).
Klar, ist ja ein uralter Hut und hat auch bei Linux 2.2 schon problemlos
funktioniert. Meine Testmaschine verwendet es auch fuer alle anderen
Platten, nur das MO unterstuetzt leider kein TCQ.
> > [...]
> > Es sollte halt schon irgendwie zusammenpassen: In meinem Beispiel
> > kopiert _ein_ Prozess auf _ein_ MO und erzeugt dabei eine Load von 4
> > obwohl der Vorgang ausser dem MO-Laufwerk selbst weder die CPUs noch die
> > I/O-Ressourcen (Busse, andere Laufwerke) signifikant belastet.
>
> Ja, die Load steigt beim Zugriff auf ATA-Devices stärker als man
> vermuten würde. Allerdings fühlt sich das System auch tatsächlich zäh
> an - da werden offenbar auch Prozesse blockiert, die nicht auf das MO
> zugreifen, und das merkt man sowohl beim Arbeiten als auch an der Load.
> Ich schätze, am ATA-Treiber könnte man noch was verbessern :-).
In meinen Rechnern gibt es nirgends ATA (war schon immer so :-). Das
genannte Problem ist zwar trotzdem vorhanden, IMHO hat es aber damit zu
tun, dass Linux 2.2 nicht vernuenftig mit seinen I/O-Buffers umgehen
kann (soll seit 2.6 ja besser geworden sein wenn die Geruechte stimmen
die ich gehoert habe). Anders gesagt: Das ist kein prinzipielles Problem
sondern ein Linux-Problem.
> > Das System als ganzes ist also alles aber nicht "ausgelastet". Ich
> > finde eine Load von 4 repraesentiert den Zustand des Systems hier
> > nicht angemessen - verglichen mit sechs R-Tasks die kein I/O machen
> > aber die gleiche Load erzeugen wuerden, das wuerde sich anders
> > anfuehlen.
>
> 6 Tasks, die nur CPU-Zeit brauchen, merke ich beim normalen Arbeiten nur
> daran, dass der Lüfter so laut ist
Also wenn ich was compiliere, dann merke ich schon ob es eine oder vier
Stunden dauert ;-)
> (ja, auch auf dem 800 MHz-Notebook
> hier) das fühlt sich nur leicht zäher an als ein unbelastetes System.
Meine Maschinen hier sind alle alt und langsam (<<800MHz) ... da spuert
man z.T. auch einen einzelnen Task der CPU will. I/O spuere ich
eigentlich nur auf MOs unter Linux.
Linux 2.2 hat ein generelles I/O-Problem. Beim spielen mit meiner
selbstgebauten RAM-Disk ist mir aufgefallen, dass es mit langsamen
Laufwerken gar nicht klar kommt. Es kann auch die Jobs fuer mehrere
Laufwerk nicht vernuenftig schachteln. Die RAM-Disk unterstuetzt kein
Disconnect (wozu auch). Wenn man darauf zugreift bleibt das System
voellig ohne Not nahezu stehen (Zugriffe auf andere Platten dauern
mehrere Sekunden). Linux rechnet aber offensichtlich mit Disconnects und
kuemmert sich bis dahin nicht um die anderen Laufwerke.
Es muesste einfach nur nach jedem RAM-Disk Transfer schauen ob noch
Requests fuer die anderen Laufwerke (die alle Disconnect und TCQ
unterstuetzen und z.T. an anderen Bussen haengen) da sind und diese
zwischenreinschieben, das allein wuerde schon richtig was bringen.
Ausserdem noch die Anzahl der Buffers die pro Laufwerk und Loop bewegt
werden der Geschwindigkeit der Laufwerke anpassen und das koennte
richtig fluessig laufen.
Micha
P.S.: Ist wie bei den Autos, bei den neuen kriegt man Strasse und Umwelt
auch nur noch weichgespuelt mit ...
Sorry, ich dachte, das wäre auch ohne nähere Kenntnisse von vmstat
verständlich, wenn wir von Context Switches pro Sekunde reden und ich
die Spalte "cs" hervorhebe.
vmstat ist ein Programm, das alle möglichen performance-relevanten
Kennwerte ausgibt (entgegen dem Namen nicht nur solche, die mit Virtual
Memory zu tun haben). Per default Anzahl der Prozesse in der Run Queue
(da hast Du deine BSD-Load Average) und im Diskwait, Memory Status, Swap
und I/O-Aktivität, Interrupts und Context Switches pro Sekunde sowiw CPU
Auslastung.
In den 7 Sekunden oben schwankten die Context-Switches zwische 78 und
5538, die CPU-Auslastung zwischen 1% und 53%, geswappt wurde nicht, etc.
> > (ja, auch auf dem 800 MHz-Notebook
> > hier) das fühlt sich nur leicht zäher an als ein unbelastetes System.
>
> Meine Maschinen hier sind alle alt und langsam (<<800MHz) ... da spuert
> man z.T. auch einen einzelnen Task der CPU will. I/O spuere ich
> eigentlich nur auf MOs unter Linux.
Also genau bei dem, das kein TCQ unterstützt, und sich somit eher wie
ein ATA-Laufwerk verhält. Das deckt sich mit meinen Beobachtungen beim
Vergleich zwischen SCSI- und ATA-basierten Systemen. Zugriffe auf
ATA-Devices haben auch negative Auswirkungen auf Prozesse, die dieses
Device gar nicht angreifen. Möglicherweise ist das ein generelles
Problem bei Devices ohne TCQ (ich spekuliere da wild vor mich hin, ich
kenne die Treiber zu wenig, um da auch nur "informed guesses" abgeben zu
können).
> Linux 2.2 hat ein generelles I/O-Problem. Beim spielen mit meiner
> selbstgebauten RAM-Disk ist mir aufgefallen, dass es mit langsamen
> Laufwerken gar nicht klar kommt.
Eine RAM-Disk ist aber eigentlich kein langsames Laufwerk, oder hast Du
die mit Ringkernspeichern realisiert?
> Es kann auch die Jobs fuer mehrere Laufwerk nicht vernuenftig
> schachteln. Die RAM-Disk unterstuetzt kein Disconnect (wozu auch).
> Wenn man darauf zugreift bleibt das System voellig ohne Not nahezu
> stehen (Zugriffe auf andere Platten dauern mehrere Sekunden).
Sehr interessant. Was kann da mehrere Sekunden brauchen, wenn Du von RAM
zu RAM kopierst? Wie groß waren denn die Buffer, die Du da geflusht
hast?
> Linux rechnet aber offensichtlich mit Disconnects und kuemmert sich
> bis dahin nicht um die anderen Laufwerke. Es muesste einfach nur nach
> jedem RAM-Disk Transfer schauen ob noch Requests fuer die anderen
> Laufwerke (die alle Disconnect und TCQ unterstuetzen und z.T. an
> anderen Bussen haengen) da sind und diese zwischenreinschieben, das
> allein wuerde schon richtig was bringen.
Nach jedem Transfer wäre wohl etwas übertrieben (da ist der Overhead
sicher größer als der Transferaufwand), aber
> Ausserdem noch die Anzahl der Buffers die pro Laufwerk und Loop bewegt
> werden der Geschwindigkeit der Laufwerke anpassen und das koennte
> richtig fluessig laufen.
das könnte schon etwas bringen. Möglicherweise ist das in neueren
Kerneln eh so - 2.2 ist ein bisschen sehr alt.
Ja jetzt wo du es schreibst ... ich war da wohl nicht mehr so fit.
> [...]
> > > (ja, auch auf dem 800 MHz-Notebook
> > > hier) das fühlt sich nur leicht zäher an als ein unbelastetes System.
> >
> > Meine Maschinen hier sind alle alt und langsam (<<800MHz) ... da spuert
> > man z.T. auch einen einzelnen Task der CPU will. I/O spuere ich
> > eigentlich nur auf MOs unter Linux.
>
> Also genau bei dem, das kein TCQ unterstützt, und sich somit eher wie
> ein ATA-Laufwerk verhält. Das deckt sich mit meinen Beobachtungen beim
> Vergleich zwischen SCSI- und ATA-basierten Systemen. Zugriffe auf
> ATA-Devices haben auch negative Auswirkungen auf Prozesse, die dieses
> Device gar nicht angreifen. Möglicherweise ist das ein generelles
> Problem bei Devices ohne TCQ (ich spekuliere da wild vor mich hin, ich
> kenne die Treiber zu wenig, um da auch nur "informed guesses" abgeben zu
> können).
Mit fehlen die ATA-Systeme zum Vergleich um das bestaetigen zu koennen.
> > Linux 2.2 hat ein generelles I/O-Problem. Beim spielen mit meiner
> > selbstgebauten RAM-Disk ist mir aufgefallen, dass es mit langsamen
> > Laufwerken gar nicht klar kommt.
>
> Eine RAM-Disk ist aber eigentlich kein langsames Laufwerk, oder hast Du
> die mit Ringkernspeichern realisiert?
Nein, mit alten 30Pin DRAM Modulen. Dass sie langsam ist liegt vor allem
daran, dass die verbauten 8Bit AVR CPUs sich weder besonders gut als
DRAM-controller noch als SCSI-Protokollchip eignen. Fuer gute
Performance muesste das in Hardware daherkommen oder mit brachialer
Rechenpower (32Bit CPUs) erschlagen werden. Aber darum gings nicht, das
Teil ist ein Spielzeug, da ist die Performance nicht so wichtig.
> > Es kann auch die Jobs fuer mehrere Laufwerk nicht vernuenftig
> > schachteln. Die RAM-Disk unterstuetzt kein Disconnect (wozu auch).
> > Wenn man darauf zugreift bleibt das System voellig ohne Not nahezu
> > stehen (Zugriffe auf andere Platten dauern mehrere Sekunden).
>
> Sehr interessant. Was kann da mehrere Sekunden brauchen, wenn Du von RAM
> zu RAM kopierst? Wie groß waren denn die Buffer, die Du da geflusht
> hast?
Die Sekunden kommen IMHO daher, dass zuviele Sektoren pro Transfer
gewaehlt werden (obwohl Transferrate niedrig und kein disconnect
moeglich) und/oder dass der I/O-Scheduler einen unpassenden Algorithmus
verwendet ("dranbleiben" solange die Daten fliessen und sich erst beim
naechsten Seek bzw. disconnect dem naechsten Laufwerk zuwenden). Der
Kernel rechnet offenbar nur mit langsamen Zugriffszeiten (und setzt dann
disconnect voraus). Dass ein device keine Zugriffszeit aber eine
niedrige Transferrate hat scheint ihn arg in Bedraengnis zu bringen.
> > Linux rechnet aber offensichtlich mit Disconnects und kuemmert sich
> > bis dahin nicht um die anderen Laufwerke. Es muesste einfach nur nach
> > jedem RAM-Disk Transfer schauen ob noch Requests fuer die anderen
> > Laufwerke (die alle Disconnect und TCQ unterstuetzen und z.T. an
> > anderen Bussen haengen) da sind und diese zwischenreinschieben, das
> > allein wuerde schon richtig was bringen.
>
> Nach jedem Transfer wäre wohl etwas übertrieben (da ist der Overhead
> sicher größer als der Transferaufwand), aber
Wieso das? Der Kernel muesste doch nur schauen ob in seinen Queues noch
Requests fuer andere Laufwerke warten (ansonsten kann er sich ja ganz
der RAM-Disk widmen). Das erzeugt ja selbst kein I/O und kostet damit
auch nicht viel.
> > Ausserdem noch die Anzahl der Buffers die pro Laufwerk und Loop bewegt
> > werden der Geschwindigkeit der Laufwerke anpassen und das koennte
> > richtig fluessig laufen.
>
> das könnte schon etwas bringen. Möglicherweise ist das in neueren
> Kerneln eh so -
Ja, 2.6 sollte das besser koennen. Kann ich hier aber nicht so einfach
draufmachen (kann man mit dem installierten GCC nicht mal compilieren,
der Rest vom System kann damit auch nicht zusammenarbeiten => Ich
muesste bei Null anfangen).
> 2.2 ist ein bisschen sehr alt.
Passend zur Maschine halt ... die laeuft bis auf das genannte Problem
sonst recht gut. Mit 2.6 wuerde mehr kaputtgehen (aic7xxx, olympic, OSS,
etc.) als die bessere I/O Performance wert ist.
Micha
--
Mails containing HTML or binary windows code are rejected.
Ah, also tatsächlich ein externes Gerät. Ich dachte bei "RAM-Disk" eher
an ein logisches Device, das einen Bereich des Hauptspeichers als
Block-Device zur Verfügung stellt (wie z.B. ramfs, cramfs, tmpfs, ...).
> > > Es muesste einfach nur nach jedem RAM-Disk Transfer schauen ob
> > > noch Requests fuer die anderen Laufwerke (die alle Disconnect und
> > > TCQ unterstuetzen und z.T. an anderen Bussen haengen) da sind und
> > > diese zwischenreinschieben, das allein wuerde schon richtig was
> > > bringen.
> >
> > Nach jedem Transfer wäre wohl etwas übertrieben (da ist der Overhead
> > sicher größer als der Transferaufwand), aber
>
> Wieso das? Der Kernel muesste doch nur schauen ob in seinen Queues noch
> Requests fuer andere Laufwerke warten (ansonsten kann er sich ja ganz
> der RAM-Disk widmen). Das erzeugt ja selbst kein I/O und kostet damit
> auch nicht viel.
Naja, bei einer RAM-Disk, wie ich sie im Kopf hatte, ist ein Transfer
ziemlich genau ein Aufruf von memcpy. Der Overhead, den zu
transferierenden Block zu finden, dürfte höher sein.
Nein, es ist schon ein eigenes - na ja, Laufwerk nicht wirklich -
device. Hier ist ein Bild davon:
http://micha.freeshell.org/ramdisk/
> > [...]
> > Wieso das? Der Kernel muesste doch nur schauen ob in seinen Queues noch
> > Requests fuer andere Laufwerke warten (ansonsten kann er sich ja ganz
> > der RAM-Disk widmen). Das erzeugt ja selbst kein I/O und kostet damit
> > auch nicht viel.
>
> Naja, bei einer RAM-Disk, wie ich sie im Kopf hatte, ist ein Transfer
> ziemlich genau ein Aufruf von memcpy. Der Overhead, den zu
> transferierenden Block zu finden, dürfte höher sein.
Ja, damit wuerde man die Problematik nicht spueren.
Micha
--
You know you've achieved perfection in design, not when you have
nothing more to add, but when you have nothing more to take away.
Befindet sich bei 2.2.26 in 'kernel/sched.c' ist aber identisch.
> Die Anzahl der Prozesse kommt nun mit count_active_tasks() ins Spiel.
> Diese Prozedur ist in timer.c definiert als:
>
> /*
> * Nr of active tasks - counted in fixed-point numbers
> */
> static unsigned long count_active_tasks(void)
> {
> return (nr_running() + nr_uninterruptible()) * FIXED_1;
> }
>
> nr_running bezieht sich dabei scheinbar auf die Angabe nr_running in
> der runqueue Struktur, die in linux-2.6.15/kernel/sched.c definiert
> ist. Das ist also die Anzahl der Prozesse in der Runqueue.
'nr_running' gibt es bei 2.2.26 auch schon, wird aber fuer die load nicht
verwendet.
> In der
> Runqueue befinden sich Prozesse mit dem Zustand TASK_RUNNING. Diese
> sind entweder schon einer CPU zugeteilt (und verbrauchen dementsprechend
> Rechenzeit), oder warten auf Zuweisung zu einer CPU durch den Scheduler.
> Prozesse im Zustand TASK_UNITERRUPTIBLE warten auf ein Ereignis, koenne
> aber im Gegensatz zu denen im Zustand TASK_INTERRUPTIBLE (die sich in
> der waitqueue befinden) nicht durch ein Signal aufgeweckt werden.
Das sieht hier leicht anders aus (auch in 'kernel/sched.c'):
|
| /*
| * Nr of active tasks - counted in fixed-point numbers
| */
| static unsigned long count_active_tasks(void)
| {
| struct task_struct *p;
| unsigned long nr = 0;
|
| read_lock(&tasklist_lock);
| for_each_task(p) {
| if ((p->state == TASK_RUNNING ||
| p->state == TASK_UNINTERRUPTIBLE ||
| p->state == TASK_SWAPPING))
| nr += FIXED_1;
| }
| read_unlock(&tasklist_lock);
| return nr;
| }
Funktioniert prinzipiell genauso, nur dass Prozesse mit TASK_SWAPPING auch
mitgezaehlt werden. Die Daten werden hier halt direkt aus den Prozess-Strukturen
ausgelesen.
> Der letzte Schritt ist nun das Macro CALC_LOAD. Dieses ist hier
> definiert:
>
> linux-2.6.15/include/linux/sched.h:
In 2.2.26 exakt das gleiche.
> Etwas anders dargestellt, sieht die Funktion so aus:
>
> load(t) = load(t-1) * exp + n(t)*(1-exp)
> [...]
Da gibt es also keinen prinzipiellen Unterschied seit 2.2.26.
> Soweit mein Verstaednis davon. Also, hier gehen wirklich nur die
> Prozesse ein
Prozesse mit TASK_SWAPPING waren bei meinem Test sicher nicht relevant (siehe
auch kswapd unten), damit sollten auch obige Berechnungen prinzipiell zum selben
Ergebnis kommen. Ich hab mir die Ausgabe von top nochmal genau angesehen
(uninteressantes gestripped):
----------------------------------------------------------------------------
12:53pm up 59 min, 2 users, load average: 2.94, 1.61, 0.65
PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND
1848 root 14 0 548 548 404 D 0 5.1 0.3 0:05 badblocks
1849 root 17 0 780 780 612 R 0 3.8 0.4 0:03 top
2 root 4 0 0 0 0 DW 0 1.1 0.0 0:02 kflushd
4 root 2 0 0 0 0 SW 0 0.9 0.0 0:00 kswapd
3 root 3 0 0 0 0 DW 0 0.3 0.0 0:01 kupdate
5 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 keventd
150 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 rpciod
151 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 lockd
----------------------------------------------------------------------------
Es faellt auf:
1) Die load ist nur noch 3
2) Die Summe der Prozesse mit D oder R Flag minus 1 (fuer top) ist 3
(R=TASK_RUNNING, D=TASK_UNINTERRUPTIBLE)
3) diverse Prozesse belegen 0Byte Speicher
Analyse
=======
zu 1):
Im Unterschied zum letzten Test habe ich mich remote eingelogged und es lief
kein lokales X. Ausserdem habe ich nichts mit dem System gemacht (Maus bewegt
etc.). Dass die load dadurch von 4 auf 3 absinkt kann wohl nur daran liegen,
dass der obige Zustand das Systems beim letzten Test irgendeinen "unbeteiligten"
Prozess derart behindert hat, dass er staendig im Zustand TASK_UNINTERRUPTIBLE
war (CPU-Zeit hat er jedenfalls keine verbraucht).
zu 2):
Das ist genau der Wert, den der Kernelcode erwarten laesst. Das top laeuft ja
nur kurz in dem Moment des updates und ist sonst "S".
Das Problem ist allerdings, dass kflushd und kupdate keine Prozesse sind sondern
Kernelthreads (siehe "zu 3)").
> und keine anderen Kernelinternas.
zu 3):
Wie man oben sieht gibt es diverse Prozesse die keinen Speicher verbrauchen,
interessant sind nur 'kflushd' und 'kupdate' da die anderen schlafen. Dazu habe
ich folgendes gefunden:
In 'fs/buffer.c':
----------------------------------------------------------------------------
/* This is the actual bdflush daemon itself. It used to be started from
* the syscall above, but now we launch it ourselves internally with
* kernel_thread(...) directly after the first thread in init/main.c */
^^^^^^^^^^^
[Bla]
int bdflush(void * unused)
{
int i;
int ndirty;
int nlist;
int ncount;
struct buffer_head * bh, *next;
int major;
int wrta_cmd = WRITEA; /* non-blocking write for LOOP */
/*
* We have a bare-bones task_struct, and really should fill
* in a few more things so "top" and /proc/2/{exe,root,cwd}
* display semi-sane things. Not real crucial though...
*/
current->session = 1;
current->pgrp = 1;
sprintf(current->comm, "kflushd");
bdflush_tsk = current;
/*
* As a kernel thread we want to tamper with system buffers
* and other internals and thus be subject to the SMP locking
* rules. (On a uniprocessor box this does nothing).
*/
lock_kernel();
[...]
----------------------------------------------------------------------------
In 'init/main.c' findet sich dann das hier:
----------------------------------------------------------------------------
[...]
/* Launch bdflush from here, instead of the old syscall way. */
kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
kernel_thread(kupdate, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
[..]
----------------------------------------------------------------------------
'kflushd' ist also bdflush (hiess bei 2.0 IIRC auch noch so in der
Prozessliste).
'kupdate' ist auch in 'fs/buffer.c':
----------------------------------------------------------------------------
/*
* This is the kernel update daemon. It was used to live in userspace
* but since it's need to run safely we want it unkillable by mistake.
* You don't need to change your userspace configuration since
* the userspace `update` will do_exit(0) at the first sys_bdflush().
*/
int kupdate(void * unused)
{
struct task_struct * tsk = current;
int interval;
tsk->session = 1;
tsk->pgrp = 1;
strcpy(tsk->comm, "kupdate");
sigfillset(&tsk->blocked);
/* sigcont will wakeup kupdate after setting interval to 0 */
sigdelset(&tsk->blocked, SIGCONT);
lock_kernel();
for (;;) {
interval = bdf_prm.b_un.interval;
if (interval)
{
tsk->state = TASK_INTERRUPTIBLE;
schedule_timeout(interval);
}
else
{
tsk->state = TASK_STOPPED;
schedule(); /* wait for SIGCONT */
}
#ifdef DEBUG
printk("kupdate() activated...\n");
#endif
sync_old_buffers();
}
}
----------------------------------------------------------------------------
Beides wuerde ich als "Kernelinterna" bezeichnen ...
Fazit1
======
Rechnet man 'kflushd' und 'kupdate' raus, wuerde eine Load von 1 uebrigbleiben
(badblocks im "D" state). Das koennte ich akzeptieren.
So wie es gerechnet wird, wird aber offenbar jede I/O-Aktion dreimal gezaehlt
(badblocks schiebt einen Block in den Kernel und die beiden Kernelprozesse
handlen ihn). Sowohl 'kflushd' als auch 'kupdate' verbrauchen dabei aber
ebenfalls keine CPU sondern warten nur auf die Platte => Somit dreimal "D" =>
Ergibt Load=3. Finde ich nicht sinnvoll ...
Fazit2
======
Wenn 2.6 bei der selben Aufgabe zu einem anderen Ergebnis fuer die Load kommt,
dann liegt es daran, dass 'kflushd' aka 'bdflush' bzw. 'kupdate' anders
implementiert sind.