Jak można ograniczyć liczbę rdzeni procesora, z których może korzystać każdy użytkownik?

18

Mamy komputer, którego procesor ma 32 rdzenie i będzie używany do uruchamiania programów przez kilku różnych użytkowników. Czy istnieje sposób na ograniczenie liczby rdzeni, z których każdy użytkownik może korzystać w dowolnym momencie, aby jeden użytkownik nie zmonopolizował całej mocy procesora?

Reza
źródło
5
Nie odpowiedź, tylko pomysł. Możesz spróbować skonfigurować kilka maszyn wirtualnych. Każdy może mieć tylko ograniczoną liczbę procesorów. Każdy użytkownik byłby tylko na jednej maszynie wirtualnej, a użytkownicy na tej maszynie wirtualnej mieliby ograniczone użycie procesora. Możliwe, że niektóre oprogramowanie do wirtualizacji ma narzędzia do obsługi tego.
ghellquist
1
@ghellquist powinieneś udzielić odpowiedzi
slebetman
@ghellquist: Prawdopodobnie chcesz czegoś tak lekkiego, jak to możliwe, takiego jak kontenery Linux, jeśli chcesz, aby różni użytkownicy widzieli tylko niektóre procesory. (np. więc kiedy uruchomią OpenMP lub inny program, który uruchamia tyle wątków, ile widzi rdzeni, uruchomi odpowiednią liczbę dla liczby rdzeni, na które pozwala każdemu użytkownikowi faktycznie użyć). Pełna wirtualizacja, podobnie jak KVM, ma koszt wydajności nawet przy wsparciu sprzętowym, takim jak VT-X lub AMD-V, z dodatkowych poziomów tabel stron, nawet gdy unika się wyjść VM, w kodzie, który powoduje jakiekolwiek braki TLB z powodu dotykania dużej ilości pamięci.
Peter Cordes
Przepraszam, ale czy jest to w ogóle potrzebne? Jako system dla wielu użytkowników, Linux domyślnie już stosuje zapobiegawcze wielozadaniowość, więc sytuacja, w której pojedynczy (nie złośliwy) użytkownik po prostu ściąga cały system dla siebie, nie powinna się pojawić.
Cubic

Odpowiedzi:

16

Chociaż jest to możliwe , jest to skomplikowane i prawie na pewno zły pomysł. Jeśli tylko jeden użytkownik korzysta obecnie z urządzenia, ograniczenie ich do N rdzeni jest marnotrawstwem zasobów. O wiele lepszym rozwiązaniem byłoby uruchomienie wszystkiego z nice:

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).

To świetne narzędzie, które określa priorytet procesu. Więc jeśli tylko jeden użytkownik coś uruchomi, otrzyma tyle czasu procesora, ile potrzebuje, ale jeśli ktoś inny uruchomi własną (również przyjemną) pracę, będzie miły i będzie się ze sobą dzielił. W ten sposób, jeśli wszyscy użytkownicy uruchamiają polecenia nice 10 command, nikt nie będzie przechwytywał zasobów (i nikt nie rzuci serwera na kolana).

Zauważ, że wysoka wartość nice oznacza niski priorytet. Jest to miara tego, jak mili powinniśmy być i im milsi jesteśmy, tym więcej się dzielimy.

Należy również pamiętać, że nie pomoże to w zarządzaniu alokacją pamięci, wpływa jedynie na planowanie procesora. Jeśli więc wielu użytkowników uruchomi wiele procesów wymagających dużej ilości pamięci, nadal będziesz mieć problem. Jeśli to jest problem, powinieneś przyjrzeć się odpowiednim systemom kolejkowania, takim jak moment obrotowy .

terdon
źródło
Dziękuję za odpowiedź. Istnieje kilka „menedżerów obciążenia”, takich jak SLURM, ale są one przeznaczone dla komputerów z wieloma węzłami. Wydaje mi się, że to ma sens, że ludzie nie opracowali podobnych aplikacji dla komputerów z jednym węzłem, ponieważ nie ma tak dużego popytu.
Reza
@Reza spróbuj nice, z tego, co opisujesz , to jest dokładnie to, czego potrzebujesz.
terdon
3
@Reza: To dlatego, że system operacyjny już to robi. W razie potrzeby automatycznie dzieli dostępne procesory na wątki / procesy.
BlueRaja - Danny Pflughoeft
13

TL; DR : Z krótkich badań wynika, że ​​można ograniczyć polecenia do określonej liczby rdzeni, jednak we wszystkich przypadkach trzeba użyć polecenia, które faktycznie wymusza ograniczenie.

grupy

Linux ma cgroupsczęsto używany dokładnie w celu ograniczenia zasobów dostępnych dla procesów. Z bardzo krótkich badań można znaleźć przykład w Arch Wiki z konfiguracją Matlab (oprogramowanie naukowe) w /etc/cgconfig.conf:

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}

Aby taka konfiguracja zadziałała, musisz uruchomić proces za pomocą cgexecpolecenia, np. Z tej samej strony wiki:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

zestaw zadań

Pokrewnych pytanie dotyczące ASK i Ubuntu Jak ograniczyć proces do jednego rdzenia procesora w systemie Linux? [duplikat] na stronie Uniksa i Linuksa pokazuje przykład zastosowania tasksetograniczenia procesorów dla tego procesu. W pierwszym pytaniu jest to osiągane poprzez analizowanie wszystkich procesów dla konkretnego użytkownika

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001

W drugim pytaniu proces rozpoczyna się tasksetsam:

$ taskset -c 0 mycommand --option  # start a command with the given affinity

Wniosek

Chociaż z pewnością możliwe jest ograniczenie procesów, wydaje się, że nie jest to takie proste dla konkretnych użytkowników. Przykład w połączonym poście Ask Ubuntu wymagałby spójnego skanowania procesów należących do każdego użytkownika i korzystania z niego tasksetna każdym nowym. O wiele bardziej rozsądnym podejściem byłoby selektywne uruchamianie aplikacji intensywnie wykorzystujących procesor, za pośrednictwem cgexeclub taskset; nie ma również sensu ograniczanie wszystkich procesów do określonej liczby CPUS, szczególnie tych, które faktycznie korzystają z równoległości i współbieżności w celu szybszego wykonywania swoich zadań - ograniczenie ich do określonej liczby procesorów może spowolnić przetwarzanie. Dodatkowo, jak wspomniano w odpowiedzi Terdona, jest to marnotrawstwo zasobów

Uruchamianie wybranych aplikacji za pośrednictwem tasksetlub cgexecwymaga komunikowania się z użytkownikami w celu poinformowania ich, jakie aplikacje mogą uruchomić, lub tworzenia skryptów opakowujących, które uruchamiają wybrane aplikacje za pomocą tasksellub cgexec.

Ponadto należy rozważyć ustawienie liczby procesów, które może odrodzić się użytkownik lub grupa, zamiast ustawiania limitu liczby procesorów. Można to osiągnąć za pomocą /etc/security/limits.confpliku .

Zobacz też

Sergiy Kolodyazhnyy
źródło
1
Cóż, istnieje cgrulesengd i cgrules.conf, aby automatycznie przenieść procesy do odpowiedniej grupy na podstawie użytkownika / grupy, zamiast polegać na użytkownikach uruchamiających swoje procesy z cgexec. Ale wygląda na to, że skonfigurowanie tego w Ubuntu jest nieco nietrywialne.
Hans-Jakob
@ Hans-Jakob Wygląda na nieco zawiły, a ponadto wymaga dodania flag jądra w GRUB-ie. Prawdopodobnie na komputerze klasy korporacyjnej, na którym masz wielu użytkowników i nie chcesz, aby powodowali awarię systemu, prawdopodobnie jest to opłacalne, ale na komputerze - zbyt dużo pracy. Dziękujemy za połączenie tego.
Sergiy Kolodyazhnyy
2
sched_setaffinity(2)mówi maska powinowactwo jest zachowana w poprzek execve(2), i że dziecko dziedziczy ją na fork(2). Jeśli więc ustawisz powłokę dla użytkownika (lub graficzną powłokę dla sesji X), wszystko, co zaczną od tej powłoki, domyślnie użyje tej samej maski koligacji.
Peter Cordes,
1
Jednym z możliwych minusów są programy, które sprawdzają, ile procesorów ma maszyna, decydując, ile wątków ma się rozpocząć; będą mieli zbyt wiele wątków na liczbę rdzeni, na których faktycznie zostaną zaplanowani. Czy dowiedziałeś się, czy grupy dyskusyjne mogą coś z tym zrobić?
Peter Cordes,
@PeterCordes Pomysł na spawnowanie brzmi interesująco. Muszę się temu przyjrzeć. Dzięki ! Jeśli chodzi o drugi komentarz, nie, nie badałem wystarczająco dużo grup w tym momencie.
Sergiy Kolodyazhnyy