load [ro].
© 2014 Jan Zulawski <fdd@altair.pw>

În Linux, pentru calcularea load-ului, se iau în considerare procesele care rulează în mod activ (în starea R) și pe lângă ele, și procesele care sunt în starea uninterruptible (D).

Ce înseamnă uninterruptible? Un proces e în starea D atunci când așteaptă un semnal, sau așteaptă terminarea unei operații de I/O (un read() sau write() către/dinspre un descriptor de fișier), de la un device.

Atunci când un proces are nevoie de date de pe un disc (așteaptă după un read()), scheduler-ul îl oprește din a mai rula în CPU, pentru a aloca slot-uri timp altor procese, deoarece starea de așteptare poate dura considerabil de mult, un timp vital pentru fluxul de procesare din CPU. { O exemplificare comparativă: un seek time uzual pentru un hard disk e undeva pe la 5ms, ceea ce reprezintă aproximativ 10 milioane de CPU cycles. }

Un proces în e starea R atunci când i se alocă CPU time, propriu-ziu. Dar un procesele petrec foarte puțin timp în starea R, efectiv. Cel mai mult sunt în starea S (sleeping), adică așteaptă după un eveniment, fie de la sistem (e.g., un răspuns TCP), sau de la utilizator (keypress, mouse action, etc.).

Așadar, fiindcă în load-ul din Linux se adună și R și D, un "load mare" înseamnă fie procesor încărcat (multe procese, scheduling intensiv), fie probleme de I/O (i.e., un disc "încet", swapping masiv, sau un filesystem ce răspunde greu).

Dar ăsta e load-ul în sine, care e de fapt un număr ce se incrementează sau decrementează. Load number-ul e incrementat cu 1 cu fiecare proces ce se adaugă în CPU run queue (starea R) sau în ready queue adică fiecare proces ce folosește CPU time, sau așteaptă după CPU (terminarea unei operații (instrucțiuni), pentru returnarea unei valori, etc.). În plus, la Linux, și procesele în starea D (e.g., citire din memorie, sau de pe disc (care poate fi directă, sau tot prin RAM), sau prin USB, în fine, sunt mai multe de zis aici, dar e legat de arhitectura în sine, iar noi vorbim la nivel de sistem).

Din `include/linux/sched.h':

extern unsigned long nr_running(void);
extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_iowait(void);
extern unsigned long nr_iowait_cpu(int cpu);

Dar când te uiți la load average, e cu totul altceva. E o medie ponderată a valorilor din trecut ale load number-ului (care sunt păstrate într-o matrice, evident), medie ce scade exponențial în timp (algoritmul e exponential weighted moving average, de fapt). Așadar, valorile load-ulului mai recente au o pondere mult mai mare decât cele din trecutul îndepărtat.


-- Jan 28, 2014.

tonight
black celebration
tonight

[ up ]