Czy wątki używają pamięci wirtualnej czy pamięci rzeczywistej?

10

Próbowałem zoptymalizować mój serwer Linux do obsługi 10 000 wątków na proces, podczas gdy obecnie robi to tylko 382. Zgodnie z tym artykułem stosowana jest następująca formuła, aby znaleźć całkowitą liczbę możliwych wątków:

number of threads = total virtual memory / (stack size*1024*1024)

Oznacza to, że wątki przechowują wszystkie swoje dane w pamięci wirtualnej. I o ile mi wiadomo, pamięć wirtualna to przestrzeń wymiany w maszynie Linux, która jest przechowywana na dysku twardym niż pamięć RAM lub pamięć podręczna.

Moje pytanie brzmi więc, czy nasze wątki używają dysku twardego do przechowywania w celu przetwarzania / przechowywania danych.

Jeśli tak, to czy ten efekt nie działa? Czy możemy zwiększyć wydajność, umieszczając je w pamięci RAM lub pamięci podręcznej? W jaki sposób?

Jeśli nie, jak dokładnie działają wątki?

Aktualizacja:

Według bezużytecznej odpowiedzi pamięć wirtualna jest systemem obejmującym z grubsza:

  • pamięć fizyczna (RAM)
  • wszystkie załączone pliki wymiany
  • sprzętowa obsługa translacji adresów wirtualnych na fizyczne i zgłaszania błędów stron, gdy adres wirtualny nie jest dostępny w pamięci fizycznej
  • Obsługa (jądra) oprogramowania: zarządzanie tabelami odnośników używanymi przez sprzęt obsługujący te błędy stron poprzez pobieranie stron z zamiany na żądanie

Tak więc wszystko, co znajduje się w pamięci wirtualnej, jest zbiorczo na RAM (pamięć rzeczywista) i na dysku twardym (pliki wymiany). I jak James wyjaśnia w swojej odpowiedzi, decyzja dotycząca Ram vs HDD jest podejmowana przez Kernel przy użyciu algorytmów takich jak LRU.

dragosrsupercool
źródło
2
chyba że twój serwer ma 10 000 procesorów / rdzeni, marnujesz czas.
@JarrodRoberson: Wiesz dlaczego?
dragosrsupercool
3
10 000 wątków nie jest dobrym sposobem na zwiększenie skali, jest to dobry sposób na zaindeksowanie serwera, więcej niż 1 wątek na procesor lub rdzeń sprawi, że kontekst serwera przełączy się i będzie działał wolniej, nie szybciej.
W szczególności, kiedy mówisz „próbuje zoptymalizować mój serwer Linux” - co próbujesz zoptymalizować? Jeśli jest to przepustowość, prawdopodobnie jeden wątek na procesor z multipleksowaniem i nieblokującymi wejściami / wyjściami będzie prawdopodobnie lepszy.
Bezużyteczne

Odpowiedzi:

12

według mojej najlepszej wiedzy pamięć wirtualna to przestrzeń wymiany na maszynie z systemem Linux

Nie, pamięć wirtualna to system obejmujący z grubsza:

  • pamięć fizyczna (RAM)
  • wszystkie załączone pliki wymiany
  • sprzętowa obsługa translacji adresów wirtualnych na fizyczne i zgłaszania błędów stron, gdy adres wirtualny nie jest dostępny w pamięci fizycznej
  • Obsługa oprogramowania (jądra) dla:
    • zarządzanie tabelami odnośników używanymi przez ten sprzęt
    • radzenie sobie z błędami stron poprzez pobieranie stron z zamiany na żądanie

Jądro ma za zadanie upewnić się, że potrzebna pamięć wirtualna jest buforowana w pamięci RAM w dowolnym momencie - chyba że piszesz własną warstwę maszyny wirtualnej przestrzeni użytkownika (jak często robią to bazy danych, iiuc), po prostu nie martw się.

Nieprzydatny
źródło
Ok, więc moje założenie dotyczące pamięci wirtualnej było nieprawidłowe. W każdym razie szybkie pytanie uzupełniające. Czy w pełni załadowana maksymalna wydajność wątków miałaby wpływ, gdyby przestrzeń SWAP była większa niż pamięć RAM?
dragosrsupercool
@dragosrsupercool: Twoja przestrzeń wymiany zawsze będzie większa niż pamięć fizyczna, w przeciwnym razie może zajść potrzeba użycia pamięci wirtualnej.
Bryan Oakley,
1
@BryanOakley: To niekoniecznie prawda. Niektóre systemy operacyjne przydzielają stronę wymiany dla każdej przydzielonej strony wirtualnej (tzn. Swap musi być co najmniej tak duży jak fizyczny). Inne systemy operacyjne przydzielają stronę wymiany tylko wtedy, gdy zachodzi potrzeba przeniesienia strony poza pamięć fizyczną (tzn. Zmiana może być mniejsza niż fizyczna). Zaletą tego pierwszego jest to, że jeśli alokacja się powiedzie, wówczas zamiana pamięci jest zawsze udana. Zaletą tego drugiego jest to, że nie trzeba pesymistycznie przydzielać dużych plików wymiany, aby uwzględnić stosunkowo rzadkie sytuacje.
mcmcc
1
@dragosrsupercool, na wydajność nie wpłynie ilość pamięci RAM, zamiana ani stosunek między nimi, chyba że brakuje pamięci RAM i faktycznie stronicuje. sar może ci powiedzieć o aktywacji stronicowania iirc (zaznaczone: sar -Bw systemie Linux).
Bezużyteczne
@Useless: Chcę zwiększyć liczbę wątków, aż całkowicie wykorzystam pamięć RAM i nie zacznę stronicować.
dragosrsupercool
14

Jeśli wątek faktycznie działa, bieżąca instrukcja i wszelkie zmienne, których używa wątek, muszą znajdować się w pamięci fizycznej.

Większość (właściwie prawie wszystkie) programy znajdują się w pamięci wirtualnej, a większość programów używa pamięci wirtualnej do przechowywania zmiennych.

Adresy wirtualne zorganizowane w porcje zwane stronami (zwykle są to bloki 4096 lub 8192 bajtów).

W dowolnym momencie każdy blok pamięci wirtualnej jest przechowywany gdzieś w pamięci rzeczywistej lub na dysku w zarezerwowanym do tego „obszarze wymiany”.

Twój kod programu dotyczy adresów wirtualnych, gdy rozgałęziasz się na adres wirtualny lub żądasz dostępu do pamięci pod adresem wirtualnym, system (zwykle na poziomie sprzętowym) lokalizuje bieżącą lokalizację żądania adresu i mapuje go na Twój adres wirtualny, jeśli adres aktualnie znajduje się na dysku, stronicuje go do prawdziwej pamięci, a następnie odwzorowuje adres.

Oczywiście, gdy cała pamięć fizyczna jest używana, jeśli coś jest stronicowane, coś innego musi być stronicowane, więc system szuka strony „Najmniej ostatnio używane” i kopiuje ją na dysk przed skopiowaniem strony, o którą prosiłeś.

W nowoczesnych systemach istnieje kilka optymalizacji i sztuczek związanych z pamięcią wirtualną.

  • Adresy są mapowane na zasadzie „na proces”, więc na przykład wszystkie programy C w Linux-ie uruchamiają proces „główny” pod tym samym adresem.
  • Może to umożliwić zajęcie kilku 32-bitowych procesów i wykorzystanie na komputerze znacznie więcej niż 4 GB, ponieważ 32-bitowy adres wirtualny można zmapować na prawdziwy adres 64-bitowy.
  • Gdy procesy się kończą lub pamięć jest „wolna”, system po prostu oznacza strony jako wolne, nigdy nie są one kopiowane z powrotem na dysk wymiany.
  • Podobnie, gdy żądany jest nowy blok pamięci, system po prostu pobiera wolną stronę w prawdziwej pamięci, nie, dyskowe operacje wejścia / wyjścia mają miejsce.
  • Funkcje uśpienia i hibernacji wymuszają skopiowanie całej pamięci do przestrzeni wymiany, aby wszystkie bieżące procesy i obecna zawartość pamięci mogły zostać odtworzone po wybudzeniu.
James Anderson
źródło
3
Wydaje się, że „wszystkie programy C w Linux-ie uruchamiają [główny] pod tym samym adresem” nie bierze pod uwagę losowości układu przestrzeni adresowej. Jest to dziś coraz częściej stosowane w celu udaremnienia różnych schematów ataków polegających na niszczeniu stosów. W przeciwnym razie dobra odpowiedź, więc +1.
CVn
7

Przede wszystkim musisz przeczytać więcej na temat pamięci komputera , ponieważ wydaje się, że brakuje Ci wiedzy w tej dziedzinie.

Wątek wykonania jest najmniejszą jednostką przetwarzania, która może zostać zaplanowana przez system operacyjny. Implementacja wątków i procesów różni się w zależności od systemu operacyjnego, ale w większości przypadków wątek jest zawarty w procesie. W tym samym procesie może istnieć wiele wątków i współużytkować zasoby, takie jak pamięć, natomiast różne procesy nie współużytkują tych zasobów.

Tak więc wątki będą wykorzystywać dostępną pamięć - bez względu na to, jaka jest dostępna. Liczba wątków, które można rozpocząć, zależy od wielkości pamięci i ilości pamięci potrzebnej na wątek. Jeśli wątek używa sterty (nie tylko stosu), potrzebuje więcej pamięci, w takim przypadku możesz rozpocząć mniej wątków.

BЈовић
źródło
@VJonvic: +1 za podstawowe wyjaśnienie wątku.
dragosrsupercool
6

Prosta odpowiedź na twoje pytanie polega na tym, że używają pamięci wirtualnej. wszystko korzysta z pamięci wirtualnej, z wyjątkiem kilku procesów związanych z systemem operacyjnym.

Z drugiej strony, gdy Twój wątek (lub dowolny wątek, w dowolnym procesie) faktycznie działa, korzysta z pamięci fizycznej. Strony pamięci powiązane z tym procesem są zamieniane na pamięć fizyczną, w której procesor wykonuje swoją pracę.

Bryan Oakley
źródło
3

Pamięć wirtualna to twoja pamięć RAM plus przestrzeń wymiany. Wirtualny oznacza po prostu, że adres widziany przez program jest inny niż adres widziany przez układ pamięci RAM. Jeśli musisz uzyskać dostęp do pamięci podczas wymiany, system operacyjny najpierw przeniesie ją do pamięci RAM. Jeśli nie chcesz żadnej zamiany, po prostu ją wyłącz. Jeśli masz wystarczającą ilość pamięci RAM, tak naprawdę jej nie potrzebujesz.

To powiedziawszy, chyba że masz 10 000 rdzeni procesora, zwiększenie do 10 000 wątków nie jest tak naprawdę „optymalizacją”. Gdy masz wystarczająco dużo wątków, aby zużyć wszystkie rdzenie, plus zapasowy lub dwa na wypadek, gdy te wątki są zablokowane, dodanie większej liczby wątków zmniejsza wydajność z powodu narzutu przełączania i braków pamięci podręcznej. Możesz nadal chcieć użyć większej liczby wątków, jeśli uprości to logikę programu, ale zmniejszysz wydajność.

Karl Bielefeldt
źródło
Tak, 10.000 to za dużo, ponieważ mój serwer to 32-bitowa maszyna z jednym rdzeniem. W rzeczywistości wątki nie są całkowitą jednostką CPU. Są to wątki przeszukiwacza, więc czasami przypominałyby oczekiwanie na odpowiedź serwera. Staram się upewnić, że procesor jest całkowicie zajęty, ale nie przeciążony ani niedociążony. Ale nadal nie rozumiem, skąd mogę wiedzieć, czy procesor jest wolny lub całkowicie zajęty. Czy jest jakieś narzędzie lub polecenie?
dragosrsupercool
Myślę, że możesz uzyskać te informacje z toppolecenia.
Karl Bielefeldt,
@KarlBieledeldt: tak, to było dokładnie to, czego szukałem. Jeszcze jedno pytanie uzupełniające: Właśnie wpadłem na pomysł przeszukiwania, że ​​jeśli ktoś jak jeden wątek może wysyłać żądanie adresów URL, a drugi wątek odbiera odpowiedź serwera, mogę zachować Wysokie wykorzystanie procesora bez użycia zbyt wielu wątków. Czy to jest możliwe? Jak wysyłanie żądania z jednego wątku podczas odbierania odpowiedzi w drugim wątku?
dragosrsupercool
2

zoptymalizuj mój serwer Linux do obsługi 10 000 wątków na proces

Jak wyjaśnili inni, jest to ogólnie źle. Wątek jest kosztowne zasobów , zwłaszcza dlatego, że ma swój własny stos wywołań (zazwyczaj megabajta), a ponieważ jest to zadanie szeregowaniu zadań przez jądro. Wątki są nawet bardziej kosztowne niż otwarte deskryptory plików .

Czytaj Systemy operacyjne: trzy łatwe utwory (podręcznik do pobrania za darmo).

Zasadniczo nie chcesz mieć wielu wątków, a na pewno nie wielu wątków możliwych do uruchomienia. Liczba możliwych do uruchomienia wątków powinna zasadniczo wynosić co najwyżej liczbę rdzeni (lub ich niewielką wielokrotność), a więc najwyżej kilkanaście. Liczba wątków w procesie może być nieco większa. Więc jeśli nie masz bardzo ekspansywnego serwera (z wieloma gniazdami i rdzeniami procesorów), nie chcesz mieć więcej niż tuzin uruchomionych wątków i stu wątków (większość z nich jest bezczynna) w twoim procesie (na pulpicie) .

W Linuksie wątki i procesy są bardzo podobne (ponieważ oba mogą być tworzone przez klon (2) ) i oba są zadaniami zaplanowanymi przez jądro. W rzeczywistości program planujący jądro planuje zadania, które mogą być wątkami wewnątrz jakiegoś procesu wielowątkowego lub pojedynczym głównym wątkiem procesu jednowątkowego (w takim przypadku nazwiesz „przetwarzać” ten pojedynczy wątek) lub wątkami jądra. Prawdopodobnie nie chcesz mieć więcej niż tysiąc zadań do zaplanowania w systemie stacjonarnym.

W systemie Linux proces to po prostu grupa wątków współużytkujących tę samą wirtualną przestrzeń adresową (i współużytkujących inne rzeczy, takie jak tabela deskryptorów plików itp.). Niektóre procesy mają tylko jeden wątek.

Wirtualnej przestrzeni adresowej jest określona przez Wikipedię jako

„zbiór zakresów adresów wirtualnych, które system operacyjny udostępnia procesowi”

(ale zobacz także tę odpowiedź wyjaśniającą, że terminologia nie jest uniwersalna, a niektóre dokumenty Microsoft używają innej i niezgodnej definicji).

W systemie Linux proc (5) jest przydatny do zrozumienia wirtualnej przestrzeni adresowej niektórych procesów. Spróbuj obu
cat /proc/self/mapsi cat /proc/$$/mapsw terminalu. Zobacz także to oraz pmap (1) i ps (1) i top (1) .

Wszystkie programy przestrzeni użytkownika działają w pewnym procesie i wykorzystują pamięć wirtualną, więc każdy proces ma swoją własną wirtualną przestrzeń adresową. Fizyczny RAM jest zasobem zarządzane przez Linuksa, a aplikacje nie mają bezpośredniego dostępu do pamięci RAM (z wyjątkiem mmap (2) -ing /dev/mem, zobacz mem (4) ).

Dlatego proces nie używa bezpośrednio pamięci RAM. Wykorzystuje pamięć wirtualną i ma własną wirtualną przestrzeń adresową. Jądro używa stronicowania zarządzać fizycznej pamięci RAM stron i zapewniają wirtualną przestrzeń adresową i proces abstrakcji . W dowolnym momencie (nawet gdy proces jest bezczynny lub działa), jądro może wysunąć strony (np. Zamienić je na dysku). Jądro konfiguruje MMU (i obsługuje wyjątki sprzętowe do pominięcia strony w niektórych procedurach obsługi przerwań , albo poprzez pobranie strony z dysku lub przez propagację błędu segmentacji do procesu, patrz signal (7) )

Możesz mieć zielone wątki powyżej wątków systemowych (ale biblioteki zielonych wątków są trudne do wdrożenia i debugowania). Spójrz na goroutiny stosowane w Go, aby znaleźć fantazyjny przykład. Zobacz także setcontext (3) .

Czasami twój system może eksperymentować z thrashowaniem . Dzieje się tak, gdy całkowita pamięć wirtualna (wymagana przez wszystkie procesy) przekracza - o duży czynnik - dostępną fizyczną pamięć RAM. Następnie komputer przestaje odpowiadać. Przeczytaj o rozmiarze zestawu rezydenta , stronicowaniu na żądanie , zestawie roboczym , nadmiernym zaangażowaniu pamięci , ASLR .

Zobacz także -dla Linux- fork (2) , klon (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , referencje (7) , pthreads (7) , futex (7) , możliwości (7) .

Basile Starynkevitch
źródło