Używam xargs
do wywołania skryptu Pythona w celu przetworzenia około 30 milionów małych plików. Mam nadzieję, że wykorzystam to xargs
do zrównoleglenia procesu. Polecenie, którego używam to:
find ./data -name "*.json" -print0 |
xargs -0 -I{} -P 40 python Convert.py {} > log.txt
Zasadniczo Convert.py
wczyta się w małym pliku json (4kb), trochę przetworzy i zapisze w innym pliku 4kb. Pracuję na serwerze z 40 rdzeniami procesora. Na tym serwerze nie działa żaden inny proces wymagający dużego procesora.
Monitorując htop (btw, czy jest jakiś inny dobry sposób monitorowania wydajności procesora?), Stwierdzam, że -P 40
nie jest tak szybki, jak się spodziewałem. Czasami wszystkie rdzenie zamarzają i zmniejszają się prawie do zera przez 3-4 sekundy, a następnie wracają do 60-70%. Następnie staram się zmniejszyć liczbę równoległych procesów do -P 20-30
, ale wciąż nie jest to bardzo szybkie. Idealnym zachowaniem powinno być przyspieszenie liniowe. Wszelkie sugestie dotyczące równoległego korzystania z xargs?
źródło
xargs -P
i>
otwiera się na warunki wyścigu z powodu problemu z linią środkową gnu.org/software/parallel/... Zamiast tego używanie GNU Parallel nie będzie miało tego problemu.Odpowiedzi:
Byłbym skłonny założyć się, że twoim problemem jest python . Nie powiedziałeś, jaki rodzaj przetwarzania jest wykonywany dla każdego pliku, ale zakładając, że po prostu przetwarzasz dane w pamięci, czas działania zostanie zdominowany przez uruchomienie 30 milionów wirtualnych maszyn (interpreterów) w Pythonie.
Jeśli możesz zrestrukturyzować swój program python, aby pobierał listę plików, zamiast jednego, uzyskasz ogromną poprawę wydajności. Następnie możesz nadal używać xargs w celu dalszej poprawy wydajności. Na przykład 40 procesów, każdy przetwarzający 1000 plików:
Nie oznacza to, że Python jest złym / wolnym językiem; po prostu nie jest zoptymalizowany pod kątem czasu uruchamiania. Zobaczysz to w dowolnym języku opartym na maszynie wirtualnej lub tłumaczonym. Na przykład Java byłaby jeszcze gorsza. Jeśli Twój program został napisany w języku C, nadal będzie istniał koszt uruchomienia osobnego procesu systemu operacyjnego do obsługi każdego pliku, ale byłoby to znacznie mniej.
Stamtąd możesz manipulować,
-P
aby sprawdzić, czy możesz wycisnąć nieco większą prędkość, być może zwiększając liczbę procesów, aby skorzystać z bezczynnych procesorów podczas odczytu / zapisu danych.źródło
Po pierwsze, rozważ ograniczenia:
Jakie jest ograniczenie każdej pracy? Jeśli to we / wy, prawdopodobnie możesz uda się uniknąć wielu zadań na rdzeń procesora, dopóki nie osiągniesz limitu We / Wy, ale jeśli jest to procesor intensywny, będzie gorzej niż bezcelowe wykonywanie większej liczby zadań jednocześnie niż w przypadku rdzeni procesora.
Moje rozumienie tych rzeczy polega na tym, że GNU Parallel dałoby ci lepszą kontrolę nad kolejką zadań itp.
Zobacz GNU równoległe vs i (mam na myśli tło) vs xargs -P, aby uzyskać bardziej szczegółowe wyjaśnienie różnic między nimi.
źródło
Jak powiedzieli inni, sprawdź, czy jesteś związany we / wy. Ponadto, strona podręcznika użytkownika xargs sugeruje używanie
-n
z-P
, nie wspominasz o liczbieConvert.py
równoległych procesów.Jako sugestię, jeśli jesteś związany we / wy, możesz spróbować użyć urządzenia blokującego SSD lub spróbować wykonać przetwarzanie w tmpfs (oczywiście w tym przypadku powinieneś sprawdzić wystarczającą ilość pamięci, unikając wymiany z powodu tmpfs presja (tak mi się wydaje), a przede wszystkim narzut związany z kopiowaniem danych.
źródło