Zastanawiałem się, czy istnieje prosty sposób na „włączenie” całego 100% procesora, aby móc szybciej uruchamiać procesy (takie jak obliczenia w języku Python).
1) Czy to jest możliwe?
2) Czy istnieje prosty sposób na powrót do normalności?
3) Czy istnieje sposób na użycie mniejszej mocy procesora, jeśli jest to pożądane?
Mam na myśli interakcję z wiersza poleceń, taką jak:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
Odpowiedzi:
Domyślnie każdy komputer będzie próbował użyć wszystkich swoich rdzeni, kiedy będzie to możliwe. Można to jednak osiągnąć tylko wtedy, gdy aplikacja jest wielowątkowa. Jeśli tak nie jest (tzn. Skrypt w języku Python, który nie korzysta z
threading
modułu), może używać maksymalnie jednego rdzenia. Odpowiada to 25% procesora czterordzeniowego procesora. Jeśli chcesz zmodyfikować skrypt, aby używał wielu rdzeni, możesz podzielić swoje obliczenia na wiele części i wielowątkowo, jak pokazano w dokumentacji Pythona .Aktualizacja:
Jak odpowiedział Anon , to nie zadziała bez współpracy z GIL Pythona (Global Interpreter Lock). Pozwala to na działanie zadań (pozornie) w tym samym czasie, ale nie pozwala na uruchamianie kodu na wielu rdzeniach. Jeśli używasz modułów napisanych w C (np. Numpy), mogą one pozwolić ci na użycie wielu rdzeni w celu obejścia tego ograniczenia. Dodatkowo, jeśli nie jest to opcja, Python oferuje wieloprocesorowanie , co pozwala na uruchomienie dowolnego zadania na wielu rdzeniach.
źródło
Nie w tym sensie, że myślę, że sugerujesz. Nie jest to także problem specyficzny dla pi, jest to ograniczenie logiczne.
Wszystkie komputery same w sobie nie mają obecnie zbyt dużej pojemności, aby ustalić, że proces działający jako pojedynczy wątek można zamiast tego uruchomić równolegle. Zauważ, że w momencie, gdy mogliby mieć taką pojemność, nie byłoby potrzeby programistów komputerowych, ponieważ system komputerowy, który mógłby to zrobić, równie dobrze mógłby napisać swój własny kod 1 ..
Rozważ następujące proste wyrażenie matematyczne:
Istnieje pewien potencjał do obliczenia tego równolegle, ale jest to logicznie ograniczone. Powiedziałbym, że nie ma sensu więcej niż dwa wątki, a nawet wtedy będzie to tylko jeden:
Wątek nr 2 przyczynił się do obliczenia 3 + 6 = 9, wykorzystanego w kroku C przez wątek nr 1, zapisując go o jeden krok. Ale to tyle, o ile przydatne będzie paralelizm. Podczas gdy wątek nr 2 mógłby obliczyć 17/9, podczas gdy nr 1 robi 6 * 17, robienie tego byłoby bezcelowe, ponieważ masz teraz dwie różne ścieżki do tego samego celu, którego nie można zrekombinować. Tj. Nr 2 może dalej działać:
I kończą się takim samym rezultatem jak wątek nr 1 (11.333), ale nie pomogli sobie nawzajem poza krokiem A, dlatego posiadanie dwóch z nich w realizacji tego celu jest stratą czasu.
(Zauważ, że ten przykład nie jest dosłowny; ma na celu wykazanie logicznej zasady. Skala, w której zadania są dzielone w kodzie użytkownika, jest znacznie większa, ale nie potrzebujesz prawdziwej lekcji programowania wielowątkowego, aby uchwycić pomysł tutaj.)
Wykorzystanie wielu procesorów wymaga do tego kodu napisanego w tym celu. Nie możesz po prostu wziąć niczego i powiedzieć: „och, użyj wszystkich 4 rdzeni i zrób to szybciej!”. Nie tak by się stało. Logicznie, wiele (lub większość) problemów i zadań wiąże się z czynnościami, które nie mogą odbywać się równolegle, muszą następować po kolei.
1. Zobacz jednak komentarz Felixa Dombka poniżej; Nie jestem ekspertem od sztucznej inteligencji. Warto również zauważyć, że zgodnie z uwagami Petera Corde'a współczesne zestawy instrukcji i procesory mogą być wykorzystywane przez system operacyjny do optymalizacji bardzo drobnoziarnistych rzeczy w równoległy sposób, a potoki sprzętowe również to robią, choć nie przez rdzenie (jeden rdzeń core ma więcej niż jedną rzecz, działając na strumieniu instrukcji w różnych punktach przed ich ostatecznym wykonaniem). Próbowałem trzymać się tutaj tematu wątków użytkowników, ponieważ myślę, że mniej więcej to masz na myśli.
źródło
add
instrukcje obok siebie, aby mogły działać w tym samym cykl zegara. Poniższe pomnożenie i podzielenie reszty będzie szeregowane według zależności danych, jak zauważyłeś.Nie dla Pythona.
Inne osoby sugerują, abyś zajął się wątkami, co jest prawidłową odpowiedzią dla większości języków, ale nie wziął pod uwagę, że używasz Pythona.
Python GIL nie pozwala na efektywne wykorzystanie wielu rdzeni.
źródło
Korzystanie z wielu rdzeni wymaga jawnego ujawnienia równoległości poziomu wątków w systemie operacyjnym, co zwykle wymaga od programisty napisania programu wielowątkowego. (Lub aby uruchomić program jednowątkowy wiele razy na różnych wejściach, takich jak kompilacja
make -j4
)Kompilatory dla niektórych języków obsługują jednak automatyczną równoległość. Na przykład C lub C ++ z OpenMP może skompilować zwykłą
for()
pętlę do programu, który uruchamia wiele wątków.Ale i tak musi się to zdarzyć, gdy napisałeś lub skompilowałeś program. Obecny sprzęt i systemy operacyjne nie mogą używać wielu rdzeni w celu przyspieszenia programu jednowątkowego.
Powiązane: W jaki sposób pojedynczy wątek działa na wielu rdzeniach? : odpowiedź: nie. Istnieją jednak inne rodzaje paralelizmu, takie jak paralelizm na poziomie instrukcji, który pojedynczy rdzeń procesora znajduje i wykorzystuje do uruchomienia jednego wątku szybciej niż jednej instrukcji na raz.
Moja odpowiedź na to pytanie dotyczy niektórych szczegółów, w jaki sposób współczesne procesory znajdują i wykorzystują drobnoziarnisty paralelizm na poziomie instrukcji. (Głównie koncentruje się na x86). To tylko część tego, jak działają normalne procesory, mając wiele instrukcji w locie, i nie jest to coś, co musisz specjalnie włączyć. (Istnieją liczniki wydajności, które pozwalają zobaczyć, ile instrukcji na zegar procesor udało się uruchomić podczas wykonywania programu lub innych środków.)
Należy pamiętać, że RPi3 używa rdzeni procesora ARM Cortex-A53 . Każdy rdzeń jest superskalarny o szerokości 2 (2 instrukcje na zegar, jak pozwala ILP), ale nie może zmienić kolejności instrukcji, aby znaleźć więcej równoległości na poziomie instrukcji i ukryć opóźnienia.
Mimo to procesor jest przetwarzany potokowo, więc łączna liczba instrukcji w locie (od pobierania i dekodowania aż do etapu zapisu zwrotnego na końcu potoku) jest znacząca. Gdy zależności danych nie ograniczają rzeczy, na każdym etapie potoku, na którym pracuje procesor, mogą znajdować się 2 instrukcje, z przepustowością 2 instrukcji na zegar. (To właśnie oznacza 2-szeroki.)
Nie może wykonywać instrukcji poza kolejnością, ale przy starannym porządkowaniu instrukcji (zwykle przez kompilator) nadal może ukryć opóźnienie instrukcji, która wymaga wielu cykli, aby jej wyjście było gotowe. (np. obciążenie, nawet jeśli trafi do pamięci podręcznej lub zwielokrotnienie zajmie wiele cykli, w porównaniu z dodawaniem gotowym do następnego cyklu). Sztuką jest uporządkowanie instrukcji asm, aby istniało wiele niezależnych instrukcji między tą, która daje wynik, a tą, która go wykorzystuje.
Posiadanie statycznego harmonogramu oprogramowania (kompilatora) jest bardziej kruche niż posiadanie sprzętu, który może wewnętrznie zmieniać kolejność, zachowując złudzenie działania w kolejności programów. Kompilatorom bardzo trudno jest wykonać tak dobrą robotę, jak nawet małe okno poza kolejnością do zamawiania instrukcji, ponieważ błędy w pamięci podręcznej są nieprzewidywalne i trudno analizować łańcuchy zależności między wywołaniami funkcji w czasie kompilacji. Liczba rejestrów jest ograniczona bez sprzętowej zmiany nazw rejestrów.
Wszystko to zapewnia niewielki komfort, gdy Twój kod działa wolniej niż chcesz. Pewnie, że pod maską jest dużo fajnych rzeczy w Cortex-A53, ale jest więcej fajnych rzeczy pod maską w Cortex-A57 (jak wykonanie poza kolejnością do 3 instrukcji na zegar), a nawet więcej w duży procesor x86, taki jak Skylake (nie wspominając o różnicach prędkości zegara).
Cortex-A53 jest dość fantastyczny w porównaniu do https://en.wikipedia.org/wiki/Classic_RISC_pipeline jak oryginalne MIPS, o których dowiesz się w klasie architektury komputerowej, ale według współczesnych standardów jest dość niskiej klasy.
źródło
java
nie jestmyapp.jar
, a na pewno nie jest jednowątkowy.Nie tak działają procesory ... w ogóle.
W obecnym stanie procesor jest w pełni zdolny do działania przy 100% obciążeniu, przy założeniu, że nie jest dławiony z powodu problemów związanych z temperaturą w temperaturze 80 stopni Celsjusza lub wyższych. Biorąc to pod uwagę, nie chcesz (generalnie) widzieć, że twój procesor jest ustawiony na 100%. Jeśli rutynowo używasz procesora w 100%, prawdopodobnie masz zbyt wiele do obsługi procesora. Spowoduje to jąkanie i ogólne niezadowolenie użytkowników.
Aby porównać z czymś bardziej fizycznym, wykorzystanie procesora przypomina samochód. Samochód prawdopodobnie może jechać z prędkością 100 km / h, ale jest duża szansa, że prędkościomierz odczytuje coś znacznie poniżej tego. Gdy jesteś w mieście, możesz nie być w stanie uzyskać prędkości około 25 km / h. Nie zmienia to jednak faktu, że samochód może jechać z prędkością 100 km / h. Po prostu nie nacisnąłeś na akcelerator wystarczająco mocno.
Jeśli po prostu sprawisz, że RPi będą robić więcej rzeczy (naciskasz więcej na akcelerator), zobaczysz wzrost wykorzystania procesora. Na przykład obserwuj wykorzystanie procesora po uruchomieniu polecenia
yes
w oknie terminala (pamiętaj, żectrl+c
kończy on polecenia terminalu). Zwiększy to twój procesor o 25%, ponieważ maksymalizuje jeden z czterech rdzeni procesora.źródło
Inne odpowiedzi zawierają szczegółowe informacje, ale nie dotyczą konkretnego pytania.
NB:
Jeśli chcesz poprawić ogólną wydajność pi, możesz zajrzeć do podkręcania. Umożliwia to szybsze działanie procesora. Wadami są zwiększone wytwarzanie ciepła, krótsza żywotność procesora i wzrost zużycia energii.
źródło
Jeśli to możliwe, sparametryzuję skrypt i wykonam go w osobnych procesach Pythona. Na przykład:
Inną alternatywą jest wspomniana już biblioteka wieloprocesowa, która pozwala rozwidlać i łączyć procesy w języku Python. Ale to także wymaga posiadania listy parametrów (takich jak nazwa pliku), dla których chcesz wykonywać obliczenia.
źródło
map
ale najwyraźniej ma ona również wiele dość skomplikowanych konstrukcji pamięci wspólnej.Myślę, że OP może nie rozumieć w pełni pojęć programowania wielordzeniowego / wielowątkowego i tego, jak trudno jest w pełni wykorzystać 100% wielordzeniowego procesora, chyba że algorytm można łatwo przekształcić w kłopotliwie równoległy problem.
Aby uzyskać więcej informacji, możesz przeczytać więcej o dobrze znanym tytule artykułu „The Free Lunch Is Over” http://www.gotw.ca/publications/concurrency-ddj.htm
źródło
Jeśli chcesz przetestować swoje RPI. Możesz uruchomić
stress
tak, jak tutaj , a następnie zobaczyć, jak używane są Twoje procesoryhtop
. Jest to przydatne, ponieważ możesz sprawdzić, czy twoje źródło zasilania jest wystarczające, jeśli nie wystarczy, twoje RPI spróbuje zużyć zbyt dużo prądu (natężenie prądu) i się wyłączy.Z drugiej strony, jeśli chcesz używać skryptów w języku Python, powinieneś zobaczyć,
joblib
który działa świetnie, gdy chcesz zrównoleglić procesy, a zatem będziesz używał liczby procesorów, którą chcesz.źródło
Chociaż wszystkie te odpowiedzi są poprawne na różne sposoby, prawdą jest, że system operacyjny automatycznie użyje różnych rdzeni do rozłożenia obciążenia. Możesz to zobaczyć za pomocą prostego programu python (temp.py powiedz)
otwórz terminal z pulpitu RPi i wpisz,
$ top
który pokaże pracę procesora. Następnie otwórz kolejny terminal, apython3 temp.py
zobaczysz, że zadanie python3 wzrasta do 100% czasu procesora. Następnie otwórz kolejny terminal i powtórz proces, aby zobaczyć, jak przejść do 400%. Tak więc na jednym poziomie, jak skomentował @Shadow, jest to takie proste i jest domyślne. Jednak projektowanie programów, które mogą wykorzystywać przetwarzanie równoległe, nie jest trywialne, jak wyjaśnili inni.źródło
Odpowiedź brzmi: TAK! Musisz po prostu napisać program, aby je rozpoznać i użyć. Programy, które to robią, mogą korzystać z rdzeni. Piszę moje, aby to zrobić w Javie, a więc mogę.
Powyższe odpowiedzi od twórców języka Python mają bardzo ograniczoną koncepcję tej odpowiedzi, więc mogą być bardzo mylące, ale odpowiedź brzmi TAK i tylko TAK!
źródło
Ponieważ OP nie określił pytona w swoim pytaniu, chciałbym zasugerować dwa bardziej nowoczesne języki, które działają dobrze na Raspberry Pi i mają bardzo łatwe sposoby używania współbieżności.
Moim ulubionym jest język Rust. Napisałem i skompilowałem programy na Pi. Rdza jest dobra, ponieważ zapobiega wielu typom błędów związanych ze wskaźnikiem i rasą, co sprawia, że pisanie współbieżnego kodu jest łatwiejsze i bezpieczniejsze. Rust jest językiem programowania systemowego, ale potrafi zrobić prawie wszystko, co C może zrobić.
Innym takim językiem jest Go (zwany także Golang, aby ułatwić wyszukiwanie). Go został stworzony przez zespół Google i jest dość dojrzałym językiem. W Go można łatwo tworzyć coroutines, które nazywają „procedurami Go”.
Oba te języki mogą kompilować kod na Raspberry Pi, nawet Pi Zero. Można je jednak skompilować krzyżowo z szybszego komputera, który jest odpowiedni dla dużych programów.
źródło