Powiedzmy, że mam 4-rdzeniowy procesor i chcę uruchomić jakiś proces w jak najkrótszym czasie. Proces ten jest idealnie równoległy, więc mogę uruchomić jego fragmenty na nieskończonej liczbie wątków, a każdy wątek zajmuje tyle samo czasu.
Ponieważ mam 4 rdzenie, nie oczekuję żadnego przyspieszenia, uruchamiając więcej wątków niż rdzenie, ponieważ pojedynczy rdzeń jest w stanie uruchomić tylko jeden wątek w danym momencie. Nie wiem dużo o sprzęcie, więc to tylko przypuszczenie.
Czy jest korzyść z uruchamiania równoległego procesu na większej liczbie wątków niż na rdzeniach? Innymi słowy, czy mój proces zakończy się szybciej, wolniej czy w mniej więcej tym samym czasie, jeśli uruchomię go przy użyciu 4000 wątków zamiast 4 wątków?
źródło
Zgadzam się z odpowiedzią @ Gonzalo. Mam proces, który nie wykonuje operacji we / wy, a oto, co znalazłem:
Zauważ, że wszystkie wątki działają na jednej tablicy, ale w różnych zakresach (dwa wątki nie mają dostępu do tego samego indeksu), więc wyniki mogą się różnić, jeśli działały na różnych tablicach.
Maszyna 1.86 to MacBook Air z dyskiem SSD. Drugi Mac to iMac z normalnym dyskiem twardym (myślę, że to 7200 obr / min). Maszyna z systemem Windows ma również dysk twardy 7200 obr./min.
W tym teście optymalna liczba była równa liczbie rdzeni w maszynie.
źródło
Wiem, że to pytanie jest dość stare, ale sytuacja ewoluowała od 2009 roku.
Należy teraz wziąć pod uwagę dwie rzeczy: liczbę rdzeni i liczbę wątków, które mogą działać w każdym rdzeniu.
W przypadku procesorów Intel liczba wątków jest definiowana przez Hyperthreading, który wynosi zaledwie 2 (jeśli są dostępne). Ale Hyperthreading skraca czas wykonania o dwa, nawet jeśli nie używasz 2 wątków! (tj. 1 potok współdzielony między dwoma procesami - jest to dobre, gdy masz więcej procesów, w przeciwnym razie nie jest tak dobre. Więcej rdzeni jest zdecydowanie lepszych!)
Na innych procesorach możesz mieć 2, 4 lub nawet 8 wątków. Więc jeśli masz 8 rdzeni, z których każdy obsługuje 8 wątków, możesz mieć 64 procesy działające równolegle bez przełączania kontekstu.
„Brak przełączania kontekstu” nie jest oczywiście prawdą, jeśli używasz standardowego systemu operacyjnego, który będzie przełączał kontekst dla wszelkiego rodzaju innych rzeczy poza twoją kontrolą. Ale to jest główny pomysł. Niektóre systemy operacyjne umożliwiają przydzielanie procesorów, więc tylko Twoja aplikacja ma dostęp / użycie tego procesora!
Z własnego doświadczenia wynika, że jeśli masz dużo wejść / wyjść, wiele wątków jest dobrym rozwiązaniem. Jeśli masz bardzo ciężką pracę wymagającą dużej ilości pamięci (odczyt źródła 1, odczyt źródła 2, szybkie obliczenia, zapis), posiadanie większej liczby wątków nie pomaga. Znowu zależy to od tego, ile danych jednocześnie odczytujesz / zapisujesz (tj. Jeśli używasz SSE 4.2 i odczytujesz wartości 256 bitów, co zatrzymuje wszystkie wątki w ich kroku ... innymi słowy, 1 wątek jest prawdopodobnie o wiele łatwiejszy do wdrożenia i prawdopodobnie prawie tak szybko, jeśli nie szybciej. Zależy to od architektury procesu i pamięci, niektóre zaawansowane serwery zarządzają osobnymi zakresami pamięci dla oddzielnych rdzeni, więc oddzielne wątki będą szybsze, zakładając, że dane są poprawnie zapisane ... i dlatego, na niektórych architektur, 4 procesy będą działać szybciej niż 1 proces z 4 wątkami).
źródło
Rzeczywista wydajność będzie zależeć od tego, ile dobrowolnego poddania się da każdy wątek. Na przykład, jeśli wątki w ogóle NIE wykonują operacji we / wy i nie używają żadnych usług systemowych (tj. Są w 100% powiązane z procesorem), wówczas 1 wątek na rdzeń jest optymalny. Jeśli wątki robią coś, co wymaga oczekiwania, musisz eksperymentować, aby określić optymalną liczbę wątków. 4000 wątków spowodowałoby znaczne obciążenie związane z planowaniem, więc prawdopodobnie nie jest to również optymalne.
źródło
Odpowiedź zależy od złożoności algorytmów używanych w programie. Wymyśliłem metodę obliczania optymalnej liczby wątków, wykonując dwa pomiary czasów przetwarzania Tn i Tm dla dwóch dowolnych liczb wątków „n” i „m”. W przypadku algorytmów liniowych optymalna liczba wątków będzie wynosić N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).
Proszę przeczytać mój artykuł dotyczący obliczeń optymalnej liczby dla różnych algorytmów: pavelkazenin.wordpress.com
źródło
Myślałem, że dodam tutaj inną perspektywę. Odpowiedź zależy od tego, czy pytanie zakłada słabe skalowanie, czy silne skalowanie.
Z Wikipedii :
Słabe skalowanie: jak zmienia się czas rozwiązania w zależności od liczby procesorów dla ustalonego rozmiaru problemu na procesor.
Silne skalowanie: jak zmienia się czas rozwiązania w zależności od liczby procesorów dla ustalonego całkowitego rozmiaru problemu.
Jeśli pytanie zakłada słabe skalowanie, wystarczy odpowiedź @ Gonzalo. Jeśli jednak pytanie zakłada silne skalowanie, jest coś więcej do dodania. W silnym skalowaniu zakładasz stały rozmiar obciążenia, więc jeśli zwiększysz liczbę wątków, zmniejszy się rozmiar danych, na których każdy wątek musi pracować. W nowoczesnych procesorach dostęp do pamięci jest drogi i lepiej byłoby zachować lokalność, przechowując dane w pamięci podręcznej. Dlatego prawdopodobną optymalną liczbę wątków można znaleźć, gdy zestaw danych każdego wątku mieści się w pamięci podręcznej każdego rdzenia (nie wchodzę w szczegóły omawiania, czy jest to pamięć podręczna L1 / L2 / L3 systemu).
Dzieje się tak nawet wtedy, gdy liczba wątków przekracza liczbę rdzeni. Załóżmy na przykład, że w programie jest 8 dowolnych jednostek (lub jednostek AU), które będą wykonywane na 4-rdzeniowej maszynie.
Przypadek 1: uruchom z czterema wątkami, przy czym każdy wątek musi ukończyć 2AU. Każdy wątek zajmuje 10 sekund ( z dużą ilością braków w pamięci podręcznej ). Przy czterech rdzeniach całkowity czas wyniesie 10s (10s * 4 wątki / 4 rdzenie).
Przypadek 2: uruchom z ośmioma wątkami, w których każdy wątek musi ukończyć 1AU. Każdy wątek zajmuje tylko 2 sekundy (zamiast 5 sekund ze względu na zmniejszoną liczbę braków pamięci podręcznej ). Przy czterech rdzeniach całkowity czas wyniesie 4 s (2 s * 8 wątków / 4 rdzenie).
Uprościłem problem i zignorowałem koszty ogólne wspomniane w innych odpowiedziach (np. Przełączniki kontekstu), ale mam nadzieję, że rozumiesz, że korzystniejsze może być posiadanie większej liczby wątków niż dostępna liczba rdzeni, w zależności od rozmiaru danych, które „ mam do czynienia z.
źródło
4000 wątków jednocześnie jest dość wysoka.
Odpowiedź brzmi: tak i nie. Jeśli robisz dużo blokowania I / O w każdym wątku, to tak, możesz pokazać znaczne przyspieszenie, wykonując do 3 lub 4 wątków na logiczny rdzeń.
Jeśli jednak nie robisz dużo blokowania, dodatkowe obciążenie związane z gwintowaniem tylko spowolni. Więc użyj profilera i zobacz, gdzie są wąskie gardła w każdym możliwym równoległym fragmencie. Jeśli wykonujesz ciężkie obliczenia, więcej niż 1 wątek na procesor nie pomoże. Jeśli wykonujesz dużo transferu pamięci, to też nie pomoże. Jeśli wykonujesz wiele operacji we / wy, na przykład w celu uzyskania dostępu do dysku lub dostępu do Internetu, tak, wiele wątków pomoże w pewnym stopniu lub przynajmniej sprawi, że aplikacja będzie bardziej responsywna.
źródło
Reper.
Zaczynam zwiększać liczbę wątków dla aplikacji, zaczynając od 1, a następnie przechodzę do czegoś takiego jak 100, przeprowadzam trzy-pięć prób dla każdej liczby wątków i buduję sobie wykres prędkości działania w stosunku do liczby wątków .
Powinieneś upewnić się, że czterordzeniowy przypadek jest optymalny, z późniejszymi nieznacznymi wzrostami czasu działania, ale może nie. Może się zdarzyć, że twoja aplikacja ma ograniczone pasmo, tzn. Zestaw danych, który ładujesz do pamięci, jest ogromny, dostajesz wiele braków pamięci podręcznej itp., Dzięki czemu 2 wątki są optymalne.
Nie możesz wiedzieć, dopóki nie przetestujesz.
źródło
Przekonasz się, ile wątków możesz uruchomić na swoim komputerze, uruchamiając polecenie htop lub ps, które zwraca liczbę procesów na twoim komputerze.
Możesz użyć strony man o komendzie „ps”.
Jeśli chcesz obliczyć liczbę wszystkich procesów użytkowników, możesz użyć jednego z następujących poleceń:
ps -aux| wc -l
ps -eLf | wc -l
Obliczanie liczby procesów użytkownika:
ps --User root | wc -l
Możesz także użyć „htop” [Dokumentacja] :
Instalowanie na Ubuntu lub Debian:
Instalowanie na Redhat lub CentOS:
Jeśli chcesz skompilować htop z kodu źródłowego, znajdziesz go tutaj .
źródło
Idealny jest 1 wątek na rdzeń, o ile żaden z wątków się nie zablokuje.
Jeden przypadek, w którym może nie być to prawdą: na rdzeniu działają inne wątki, w którym to przypadku więcej wątków może dać Twojemu programowi większy wycinek czasu wykonania.
źródło
Jednym z przykładów wielu wątków („puli wątków”) w porównaniu do jednego na rdzeń jest implementacja serwera WWW w systemie Linux lub Windows.
Ponieważ gniazda są odpytywane w Linuksie, wiele wątków może zwiększyć prawdopodobieństwo, że jeden z nich odpytuje odpowiednie gniazdo we właściwym czasie - ale ogólny koszt przetwarzania będzie bardzo wysoki.
W systemie Windows serwer zostanie zaimplementowany przy użyciu portów zakończenia we / wy - IOCP - które spowodują zdarzenie aplikacji: jeśli system we / wy zakończy działanie, system operacyjny uruchamia wątek rezerwowy, aby go przetworzyć. Po zakończeniu przetwarzania (zwykle z inną operacją We / Wy, jak w przypadku pary żądanie-odpowiedź) wątek wraca do portu IOCP (kolejki), aby czekać na następne zakończenie.
Jeśli żadne operacje we / wy nie zostały zakończone, przetwarzanie nie jest konieczne i wątek nie jest uruchamiany.
Rzeczywiście, Microsoft zaleca nie więcej niż jeden wątek na rdzeń w implementacjach IOCP. Dowolne I / O mogą być dołączone do mechanizmu IOCP. W razie potrzeby wniosek może również zostać wysłany przez MKOl.
źródło
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
mówiąc z obliczeń i punktu widzenia związanego z pamięcią (obliczenia naukowe) 4000 wątków spowoduje, że aplikacja będzie działać bardzo wolno. Częścią problemu jest bardzo duży narzut związany z przełączaniem kontekstu i najprawdopodobniej bardzo słaba lokalizacja pamięci.
Ale zależy to również od Twojej architektury. Z miejsca, w którym słyszałem, procesory Niagara powinny być w stanie obsłużyć wiele wątków na jednym rdzeniu za pomocą zaawansowanej techniki tworzenia potoków. Jednak nie mam doświadczenia z tymi procesorami.
źródło
Mam nadzieję, że ma to sens, sprawdź wykorzystanie procesora i pamięci i ustaw wartość progową. Jeśli wartość progowa zostanie przekroczona, nie zezwalaj na tworzenie nowego wątku, w przeciwnym razie zezwól ...
źródło