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!

Widzisz?

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

Author: Vivek Vermani, 2014-02-07

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;
}
 89
Author: Sergei Kurenkov,
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