Dynamicznie wyłączasz rdzenie w energooszczędny sposób?

3

Szukam mechanizmu do dynamicznego wyłączania rdzeni w systemie Linux, aby zminimalizować zużycie energii.

Niestety, wyłączenie rdzeni przy użyciu następującego prostego podejścia faktycznie zwiększa moc, na podstawie odczytów z Watts Up? Pro mierzący całkowitą moc systemu:

echo 0 > /sys/devices/system/cpu/cpu7/online

Moje doświadczenie wydaje się potwierdzone przez innych (chociaż ten błąd został oznaczony jako „ZAMKNIĘTA PATCH_ALREADY_AVAILABLE”): https://bugzilla.kernel.org/show_bug.cgi?id=5471

Ponieważ maszyna jest rozładowana, chcę, aby wszystkie rdzenie oprócz jednego (lub może dwóch „rdzeni”, ponieważ procesor jest hiperwątkowy) znajdowały się w możliwie najgłębszym stanie uśpienia. Wydaje się, że nie dzieje się to samo, w oparciu o dane wyjściowe acpitool:

Processor ID           : 7
Bus mastering control  : no
Power management       : yes
Throttling control     : no
Limit interface        : no
Active C-state         : C0
C-states (incl. C0)    : 3
Usage of state C1      : 899 (99.3 %)
Usage of state C2      : 6 (0.7 %)

BTW, dla mnie jednym zamieszaniem jest to, że acpitool i / proc / acpi wydają się nie zgadzać co do dostępnych stanów C, a może używają różnych schematów nazewnictwa.

$ cat /proc/acpi/processor/CPU7/power 
active state:            C0
max_cstate:              C8
maximum allowed latency: 2000000000 usec
states:
    C1:                  type[C1] promotion[--] demotion[--] latency[001] usage[00000000] duration[00000000000000000000]
    C2:                  type[C2] promotion[--] demotion[--] latency[017] usage[00001248] duration[00000000001877531423]
    C3:                  type[C3] promotion[--] demotion[--] latency[017] usage[00000006] duration[00000000000012580727]

To wydaje się wskazywać, że istnieją 4 stany C (C0-C3), ale acpitool zgłasza tylko 3 stany C.


Naprawdę sprowadza się to do dwóch pytań:

  1. Czy istnieje (bezpieczny) sposób, aby zmusić poszczególne rdzenie do określonego stanu snu (stan C) i zmusić je do pozostania tam, dopóki ich wyraźnie nie obudzę?
  2. Alternatywnie, w jaki sposób mogę poprawić zdolność systemu operacyjnego do bardziej spójnego wprowadzania rdzeni w głębsze stany uśpienia?

Zauważ, że opóźnienie budzenia się z głębszych stanów snu nie stanowi problemu. FWIW, używam Ubuntu 10.04.3 (jądro 2.6.32-38) na Intel i7 920.

Michael Boyer
źródło
Próbowałeś powertop? Jakie to sugestie? W moich systemach zmniejszyło to moc jałową o około 15 W. Nie wiem, czy zaznaczanie poszczególnych rdzeni jest czymś, co robi bezpośrednio, czy pozostawia to harmonogramowi, ale oszczędności energii są namacalne. Znacząco zmniejszyło liczbę pobudek na minutę, więc wyłączenie rdzeni jest teraz znacznie bardziej prawdopodobne.
Supercilious
Dzieki za sugestie. Słyszałem o powertop, ale nigdy go nie wypróbowałem; Nie zdawałem sobie sprawy, że to podpowiedzi! Wypróbuję je, kiedy będę miał szansę, i zobaczę, jaki mają wpływ. Dla przypomnienia, nadal jestem zainteresowany znalezieniem sposobu, aby zagwarantować, że niektóre rdzenie wejdą (i pozostaną) w określonym stanie snu.
Michael Boyer

Odpowiedzi:

-1

Wszystkie powyższe metody ograniczenia stanów C będą trwałe (do momentu ponownego uruchomienia systemu). Jeśli chcesz mieć system o bardzo niskim opóźnieniu w określonych godzinach, ale chcesz uzyskać więcej oszczędności energii w innym czasie, istnieje metoda dynamicznej kontroli, które stany C są używane.

Aby dynamicznie kontrolować stany C, otwórz plik / dev / cpu_dma_latency i zapisz do niego maksymalne dopuszczalne opóźnienie. Zapobiegnie to użyciu stanów C z opóźnieniami przejścia wyższymi niż podana wartość, o ile plik / dev / cpu_dma_latency jest otwarty. Zapisanie maksymalnego dopuszczalnego opóźnienia wynoszącego 0 utrzyma procesory w C0 (podobnie jak użycie parametru jądra „idle = poll”), a zapisanie niskiej wartości (zwykle 5 lub mniej) powinno zmusić procesory do C1 w stanie bezczynności. Dokładna wartość wymagana do ograniczenia procesorów do stanu C1 zależy od różnych czynników, takich jak używany sterownik bezczynności, używane procesory i ewentualnie tabele ACPI w systemie. Można również zapisać wyższe wartości, aby ograniczyć użycie stanów C z opóźnieniem większym niż zapisana wartość.

Jednym prostym sposobem na to jest skompilowanie prostego programu, który napisze do tego pliku i pozostanie otwarty, dopóki nie zostanie zabity. Przykład takiego programu znajduje się poniżej i można go skompilować, wycinając i wklejając kod do pliku o nazwie setcpulatency.c, i uruchamiając polecenie „make setcpulatency”. Tak więc, aby zminimalizować opóźnienia w określonych godzinach, powiedzmy od 8 rano do 5 po południu, zadanie crona można ustawić tak, aby działało o 8 rano. To zadanie cron może uruchomić setcpulatency w tle z argumentem 0, z wpisem w tabeli cron w następujący sposób:

00 08 * * * /path/to/setcpulatency 0 &

Następnie o godzinie 17:00 kolejne zadanie crona może zabić każdy program, który trzyma / dev / cpu_dma_latency otwarty:

00 17 * * * kill -9 `lsof –t /dev/cpu_dma_latency`

Oczywiście jest to tylko przykład pokazujący, w jaki sposób można dynamicznie kontrolować stany C ... usługa crond jest często wyłączona w środowiskach o niskim opóźnieniu, ale te kroki można wykonać ręcznie lub uruchomić w inny sposób.

#include <stdio.h>
#include <fcntl.h>

int main(int argc, char **argv) {
   int32_t l;
   int fd;

   if (argc != 2) {
      fprintf(stderr, "Usage: %s <latency in us>\n", argv[0]);
      return 2;
   }

   l = atoi(argv[1]);
   printf("setting latency to %d us\n", l);

   fd = open("/dev/cpu_dma_latency", O_WRONLY);

   if (fd < 0) {
      perror("open /dev/cpu_dma_latency");
      return 1;
   }

   if (write(fd, &l, sizeof(l)) != sizeof(l)) {
      perror("write to /dev/cpu_dma_latency");
      return 1;
   }
}
Kroka
źródło
To jest niezredagowana wklejka z pliku PDF firmy Dell, w jaki sposób zrobić coś przeciwnego do tego, o co poprosił PO (tymczasowo zapobiegaj rdzeniom na biegu jałowym, aby uzyskać maksymalną wydajność). Bezczynność jest domyślnym zachowaniem w większości przypadków.
akom