Zrozumienie średniego obciążenia a wykorzystanie procesora [zamknięte]
Ok, sam jestem użytkownikiem Windowsa, więc moja wiedza o Linuksie jest trochę ograniczona.
Jednak to było moje ogólne zrozumienie, że "średnia obciążenia" jest wskaźnikiem, ile przetwarzanych jest uruchamianych w danym momencie, średnio w ciągu ostatniej minuty, pięciu minut i... piętnaście minut?
W każdym razie, monitorowałem mój serwer, ponieważ mieliśmy wielkie otwarcie i wiele osób!
Oglądałem top
i zauważyłem coś to było sprzeczne z tym, co myślałem, że wiem.
Jeśli średnie obciążenie wynosi 7, z 4 procesorami hyper-threaded, nie powinno to oznaczać, że procesor pracuje do około 7/8 pojemności?
Dlaczego, to pokazywał 50.0% id? Jak może być bezczynny przez połowę czasu?
Nie rozumiem XD
1 answers
Po pierwsze, top
nie oblicza load average
siebie. Po prostu odczytuje {[3] } z pliku /proc/loadavg
(strace
pokazuje, że top
otwiera /proc/loadavg
, a następnie odczytuje z niego okresowo). man proc
mówi to dla /proc/loadavg
:
/proc / loadavg
Pierwsze trzy pola w tym pliku to wartości średniej obciążenia, które liczba zadań w kolejce uruchamiania (stan R) lub oczekujących na wejście/wyjście dysku (stan D) uśrednione przez 1, 5 i 15 minut. Są takie same jak liczby średnie obciążenia podane przez uptime(1) i inne programy. Na czwarte pole składa się z dwóch liczb oddzielonych ukośnikiem (/). Na pierwsza z nich to liczba aktualnie wykonujących szeregowanie jądra encje (procesy, wątki); będzie to mniejsze lub równe liczba procesorów. Wartość po ukośniku jest liczbą jądra jednostki planowania, które obecnie istnieją w systemie. Piąty pole jest PID procesu, który został ostatnio utworzony na system.
Więc load average
pokazuje liczbę zadań w kolejce uruchamiania. I wyświetlane są trzy pierwsze wartości z /proc/loadavg
przez top
. Jeśli uruchomisz cat /proc/loadavg
, zobaczysz wszystkie wartości w pliku.
Przy okazji wydaje się być błąd w opisie czwartego pola. Napisałem prosty program testowy w C++, który odczytuje liczbę całkowitą N Z wejścia, a następnie tworzy N wątków, które po prostu uruchamiają pętlę bezokolicznika. Kiedy uruchamiam mój program i proszę go o utworzenie 256 wątków. Mam tylko 8 procesorów z HT. Jednak widzę to w pliku:
>cat /proc/loadavg
74.44 21.04 10.59 259/931 17293
Najwyraźniej 259 jest większy niż liczba CPU na moim komputerze. Ten post http://juliano.info/en/Blog:Memory_Leak/Understanding_the_Linux_load_average mówi o tym samym - jest błąd w opisie load average
. To jest cytat:
Warto zauważyć, że obecne Wyjaśnienie na stronie podręcznika proc (5) (od wersji man-pages 3.21, marzec 2009) jest źle. Informuje o pierwszy numer czwartego pola jako liczba aktualnie wykonujących jednostek planowania, a więc przewiduje, że nie może być większa niż liczba procesorów. To nie pasuje do rzeczywistej realizacji, gdzie to wartość informuje o bieżącej liczbie uruchomionych wątków
Więc, odpowiadając na twoje pytania:
Jeśli średnie obciążenie wynosi 7, z 4 procesorami hyper-threaded, nie powinno to oznaczać, że procesor pracuje do około 7/8 pojemności?
Nie oznacza to tylko, że masz 7 uruchomionych procesy w kolejce zadań średnio.
Dlaczego, więc pokazywał 50.0% id? Jak może być bezczynny przez połowę czasu?
Ponieważ load average
nie oznacza "% pojemności procesora". Twoje wątki po prostu używają tylko 50% CPU i 50% czasu robiąc coś innego.
I wreszcie. Poniżej mój prosty test. Aby zbudować użyj g++ -pthread my_test.cpp -o my_test
. Uruchom {[18] } i zobacz swój czas bezczynności, gdy wątki działają stale i nie trać czasu na czekanie na nic. Lub uruchom ./my_test 128
, aby zobaczyć, że ładunek średnia może być znacznie większa niż liczba procesorów.
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
static void* __attribute__ ((noinline))
my_thread_func(void * arg)
{
printf("Thread %lld:\n", (long long)pthread_self());
volatile long long i = 0;
while (1) {
++i;
}
return 0;
}
int
main(int argc, char *argv[])
{
int num_threads;
pthread_t *my_threads;
num_threads = atoi(argv[1]);
my_threads = new pthread_t[num_threads];
for (int tnum = 0; tnum < num_threads; tnum++) {
pthread_create(&my_threads[tnum], NULL, &my_thread_func, NULL);
}
sleep (600);
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-04 16:28:24