Jaki język programowania jest najczęściej używany w obliczeniach o wysokiej wydajności? I dlaczego? [Zamknięte]


25

Uważam, że w HPC używa się dużej ilości Fortranu, ale nie jestem pewien, czy dzieje się tak tylko ze względów starszych.

Funkcje współczesnych języków programowania, takie jak wyrzucanie elementów bezużytecznych lub polimorfizm w czasie wykonywania, nie są odpowiednie dla HPC, ponieważ szybkość ma znaczenie, więc nie wiem, gdzie jest C #, Java lub C ++.

jakieś pomysły?


9
C ++ nie ma śmietnika i nie wymaga użycia polimorfizmu środowiska uruchomieniowego.
Jason Baker,

@Jason Moim zamiarem jest dowiedzieć się, jakie cechy C ++ sprawiają, że jest to przekonujący przypadek dla HPC.
Fanatic23,

@ Fanatic23 - Rozumiem. Chciałem tylko to zanotować. :-)
Jason Baker

1
@ Fanatic Wish mógłbym powiedzieć tak, ale nie mam za dużo ... Mam jednak wiele linków dotyczących niektórych problemów z wydajnością w .NET / językach funkcjonalnych. Być może będziesz w stanie poskładać koncepcje w mentalny sposób, aby poznać pewne ograniczenia wydajności: msdn.microsoft.com/en-us/library/0xy59wtx.aspx stackoverflow.com/questions/2909282/... msdn.microsoft.com/en -us / magazine / cc163329.aspx en.wikipedia.org/wiki/Just-in-time_compilation
Rei Miyasaka

1
Myślę jednak, że jeśli potrzebujesz naprawdę dobrego czasu reakcji, szukasz systemu operacyjnego w czasie rzeczywistym, takiego jak QNX: en.wikipedia.org/wiki/QNX
Rei Miyasaka

Odpowiedzi:


11

Widziałem dużo Java używanego do HPC w obszarach, w których (1) jest mało starszego kodu oraz (2) czas programowania i jakość kodu mają znaczenie. Typowymi domenami aplikacji są finanse, eksploracja danych lub bioinformatyka.

To naprawdę zależy od aplikacji (życie istnieje poza algebrą liniową), ale wydajność najnowszych JVM jest często na równi z kodem C. Czasami szybciej, gdy JVM jest w stanie wykonać w czasie wykonywania sprytne optymalizacje, których nie są w stanie zrobić kompilatory statyczne (C, Fortran). I zdecydowanie szybciej, gdy jest dużo obliczeń symbolicznych.

Biorąc pod uwagę ustaloną ilość czasu na rozwój programu, wynikowy kod Java jest konsekwentnie szybszy niż kod C. HPC w Javie zdecydowanie ma sens, gdy kod jest często rozwijany lub modyfikowany. Inną ważną cechą jest mobilność kodu na różnych urządzeniach.

Odniesienia znajdziesz w http://ateji.blogspot.com/2010/09/java-for-high-performance-computing.html

Jeśli chodzi o założenie Fortran, że dwa adresy są unikalne, pracujemy nad narzędziem do analizy statycznej, które umożliwi podobne optymalizacje kodu w językach wysokiego poziomu, ale bez bitu „Złe rzeczy mogą się zdarzyć”. Skontaktuj się ze mną, jeśli jesteś zainteresowany.


14
Nitpick: Optymalizacje JIT są dostępne dla statycznych kompilatorów, jeśli chcesz trochę popracować. Zarówno GCC, jak i MS Visual Studio obsługują optymalizacje profilowane, które optymalizują przy użyciu zapisanych danych środowiska wykonawczego. Trochę mylące jest sugerowanie, że istnieją optymalizacje „których nie mogą zrobić kompilatory statyczne (...)”.
Corbin,

4
Nie wiem, dlaczego jest to zaakceptowana odpowiedź, nic w tym poście nie zawiera pozorów prawdy. Języki oparte na języku C zawsze będą lepsze niż Java, ponieważ Java jest maszyną wirtualną zależną z natury od innego języka. Ponadto wszystko, co można osiągnąć w Javie, można osiągnąć w C przy mniejszym obciążeniu. Języki oparte na języku C nigdy nie przestaną być językiem „wykonującym”.
Mike,

31

W moim wieloletnim doświadczeniu, do 5 lat temu, zawsze był to Fortran i C. Który z nich zależał głównie od tego, czy ludzie pochodzili bardziej z inżynierii, czy więcej ze szkoły myślenia CS (nie wiem, jak to poprawić) , okej? :-)

W tym, co robiliśmy, Fortran był prawie wyłącznie używany.

Z tego, co czytałem dzisiaj, dzięki nowym aktualizacjom standardu F2003 / 08 i wprowadzeniu technologii Co-Arrays wydaje się, że znów nabiera rozpędu.

Również jeden, jeśli nie nieco stronniczy artykuł - Idealny język programowania HPC


16

Myślę, że dla prawdziwego pedału do metalu jedynym prawdziwym wyborem jest Fortran. Powodem jest to, że najważniejszą rzeczą w wykorzystaniu niskiego poziomu ILP (paraliżu poziomu instrukcji) jest ujednoznacznienie adresu pamięci. Reguły defacto w Fortran pozwalają kompilatorowi ustalić, że dwa adresy są unikalne (a zatem kolejność ładowań i magazynów, a nawet sklepów i magazynów można zamieniać bez ryzyka wygenerowania niepoprawnego kodu). C pozostawia zbyt duży zakres nakładających się wskaźników, aby kompilator mógł wyodrębnić z kodu tyle równoległości na niskim poziomie.

Również wyrównanie tablicy, linie pamięci podręcznej wrt i granice SSE / AVX są ważne dla generowania i wykonywania wydajnych pętli. Jeśli tablice są przekazywane przez wspólne bloki, kompilator / moduł ładujący może zapewnić, że wszystkie tablice zaczynają się na tych samych granicach wyrównania adresu, i można wykorzystać bardziej wydajne ładowanie i przechowywanie SSE / AVX. Nowszy sprzęt może obsługiwać niewyrównany dostęp do pamięci, ale ponieważ dostęp do pamięci nie jest odpowiednio wyrównany, częściowe użycie linii pamięci podręcznej skutkuje niższą wydajnością. Nawet jeśli programista C poprawnie wyrówna wszystkie swoje tablice, czy istnieje mechanizm komunikacji z kompilatorem?

Podsumowując, dwie najważniejsze kwestie to niezależność adresów pamięci i rozpoznanie przez kompilator, że struktury danych, do których uzyskano dostęp, mają takie samo „naturalne” wyrównanie, jakiego chce sprzęt. Do tej pory Fortran najlepiej wykonuje te dwa zadania.


2
Niedawno przeprowadziłem mały eksperyment, znalazłem liczbę wyskakujących ciągów 64000 bitów, reprezentowanych jako długa, długa tablica bez znaku. Użyłem dokładnie tego samego algorytmu, używając wielu interesujących wartości logicznych i spakowanych danych arytmetycznych. W C z -O3 długo trwało 10 zegarów, podczas gdy w fortran Intel Fortran 10.1, przy domyślnej optymalizacji było to 6,5! I każdy programista uważa, że ​​C jest lepszy w kręceniu bitów! Założenia Fortra defacto umożliwiają bezpieczne generowanie wydajniejszego kodowania instrukcji niskiego poziomu.
Omega Centauri

4
Powinno to brzmieć: „Reguły defacto w Fortranie pozwalają kompilatorowi na ZAŁOŻENIE, że dwa adresy są unikalne ...”. Wszystkie podręczniki informują, że kompilator może to przyjąć i ostrzegają W SZCZEGÓŁACH, że złe rzeczy mogą się zdarzyć, jeśli złamiesz to założenie.
John R. Strohm,

15

Tylko jakaś anegdotyczna notatka. Sam nie wykonałem obliczeń o wysokiej wydajności.

Do obliczeń (dzielenie liczb) Fortran i C. Tak, to z powodów starszej generacji:

  • Duża dostępność kodu źródłowego domeny publicznej i przepisów.
  • Oba obsługują MPI .
  • Oba języki są kompilowane.
  • Kompilatory dla obu języków są dostarczane przez wszystkie systemy operacyjne HPC i dostawców.
  • Kompilatory wektoryzacji są dostępne.
  • Oba wymagają szalonego poziomu poprawiania, aby uzyskać wysoką wydajność po przeniesieniu do innego klastra (inny rozmiar pamięci, liczba procesorów itp.)
    • To faktycznie wyjaśnia, dlaczego otwarty kod źródłowy jest ważny: poprawianie jest konieczne, dlatego oryginalny przepis musi być napisany w języku, który jest odpowiedni do ręcznego dostosowywania.

Obecnym trendem w dzieleniu liczb jest pisanie generatorów programów, które automatyzują modyfikację kodu źródłowego w celu zoptymalizowania wydajności, biorąc pod uwagę cechy klastra. Generatory te często generują w C.

Drugim trendem jest pisanie w jakimś wyspecjalizowanym dialekcie C dla określonych GPU lub Cell BE.

W przypadku prac nienumerycznych, takich jak programy przetwarzające dane z bazy danych (ale nie z samej bazy danych), znacznie tańsze jest uruchamianie na klastrach maszyn „towarowych” bez drogiego, dostosowanego sprzętu sieciowego. Jest to zwykle nazywane „przetwarzaniem o wysokiej przepustowości”. Python jest tutaj językiem nr 1 (przy użyciu słynnego narzędzia Map Reduce). Przed Pythonem projekty przetwarzania wsadowego mogą być pisane w dowolnym języku i zwykle są wysyłane przez Condor .


1
Czy mógłbyś trochę rozwinąć część „szalonego poziomu podkręcania”?
Wieża

Centrum komputerowe zatrudnia doktorantów w celu zmiany kolejności połączeń MPI, aby przyspieszyć działanie.
rwong

(?) Pierwsze słowo tutaj, ale myślę, że praktyki różnią się.
Wieża

Było to centrum badawcze zajmujące się modelowaniem klimatu.
rwong

4

Pracowałem nad bardzo BARDZO intensywnym obliczeniem kodu w (dysz!) C #.

Buduję implementację FDTD GPGPU do modelowania optycznego. W małym klastrze (128 procesorów) wiele naszych symulacji trwa kilka tygodni. Implementacje procesorów graficznych działają jednak około 50 razy szybciej - i to na karcie NVidia klasy konsumenckiej. Mamy teraz serwer z dwiema dwuprocesorowymi kartami GTX295 (kilkaset rdzeni) i wkrótce otrzymamy trochę Teslasa.

Jak to się ma do twojego języka? W ten sam sposób, w jaki używany wcześniej kod C ++ FDTD był związany z procesorem, są one powiązane z procesorem graficznym, więc ( bardzo mała) różnica mocy zarządzanego i natywnego kodu nigdy nie wchodzi w grę. Aplikacja C # działa jak przewodnik - ładuje jądra OpenCL, przekazuje dane do i z GPU, zapewnia interfejs użytkownika, raportowanie itp. - wszystkie zadania, które są uciążliwe w C ++.

W przeszłości różnica w wydajności między kodem zarządzanym i niezarządzanym była na tyle znacząca, że ​​czasami warto było pogodzić się z okropnym modelem obiektowym C ++, aby uzyskać dodatkowe kilka procent prędkości. Obecnie koszt rozwoju C ++ w porównaniu z C # znacznie przewyższa korzyści większości aplikacji.

Ponadto większość różnic w wydajności nie będzie wynikać z wyboru języka, ale z umiejętności programisty. Kilka tygodni temu przeniosłem operację pojedynczego podziału z wnętrza potrójnie zagnieżdżonej pętli (przechodzenie przez tablicę 3D), co skróciło czas wykonania dla danej domeny obliczeniowej o 15%. Wynika to z architektury procesorów: podział jest powolny, co jest jedną z tych twarzy, które po prostu gdzieś potrzebujesz.


1
c ++ ma model obiektowy? Ale wygląda na to, że powinieneś był użyć języka skryptowego do pisania kontrolerów - jeśli C # jest lepszy niż C ++ z powodu prędkości deweloperskiej, to python (lub lua itp.) Jest podobnie lepszy niż C #.
gbjbaanb,

3
@gbjbaanb Niekoniecznie. Ta implementacja jest związana z GPU, ale przejście na język skryptowy może bardzo łatwo to zmienić. C # jest skompilowany i ma bardzo ładny optymalizator. Kompilowane, mocno pisane języki to twoi przyjaciele! Mniej rygorystyczne języki skryptowe zwykle powodują wydłużenie czasu programowania dla każdego dość złożonego projektu.
3Dave

1
Minęło siedem lat. Dużo się nauczyłem. c ++ jest całkiem niesamowity, C # jest również niesamowity, naprawdę lubię Pythona i: CPU perf wciąż ma znaczenie.
3Dave

3

Fortran jest najczęstszy, głównie ze względu na starsze wersje (ludzie nadal używają starego kodu) i znajomość (większość osób, które wykonują HPC, nie zna innych rodzajów języków).

Funkcje współczesnych języków programowania, takie jak wyrzucanie elementów bezużytecznych lub polimorfizm w czasie wykonywania, nie są odpowiednie dla HPC, ponieważ szybkość ma znaczenie, więc nie wiem, gdzie jest C #, Java lub C ++.

To ogólnie nie jest prawda. Klasyczna HPC zajmowała się głównie algebrą liniową z liczbami maszynowo precyzyjnymi. Jednak współczesne HPC coraz częściej korzysta z superkomputerów w celu uzyskania większej różnorodności chrupania, takich jak obliczenia symboliczne z dowolnymi wyrażeniami matematycznymi zamiast liczb dokładności maszynowych. Daje to zupełnie inną charakterystykę używanym narzędziom i nierzadko używa się języków programowania innych niż Fortran, ponieważ obliczenia symboliczne mogą być niezwykle trudne bez GC i innych rodzajów kompilatora optymalizującego, takiego jak kompilator optymalizujący dopasowanie wzorców OCamla.

Na przykład przeczytaj ten artykuł Fischbacher i in. co mówi: „autorzy mają mocne podstawy, by sądzić, że może to być jak dotąd największe obliczenie symboliczne”.


Fortran jest powszechny, ponieważ wiele osób używa czasu superkomputera do przeprowadzania symulacji układów fizycznych, takich jak globalne prognozowanie pogody, oraz implementacja wymaganych algorytmów w Fortranie bardzo przejrzysta i zwięzła.
Sharpie

3

Fortran, z kilku dobrych i niezbyt dobrych powodów. W przypadku poważnych problemów matematycznych dobrym powodem jest istnienie obszernych bibliotek (BLAS, LAPACK) sprawdzonych podprogramów, wszystkie napisane w Fortranie (choć można je wywoływać z C i C ++).

Niezbyt dobrym powodem jest rzekoma przewaga wydajności Fortran nad C / C ++. Optymalizatory są całkiem dobre i niewiele osób rozumie, że korzyść z optymalizacji fragmentu kodu jest proporcjonalna do procentu czasu, w którym jest on zajęty, co w prawie całym kodzie jest prawie zerowe.

Innym niezbyt dobrym powodem jest luka kulturowa między programistami CS i nie-CS. Programiści naukowi zwykle uczą się złych nawyków w Fortranie i patrzą z góry na programistów CS i złe nawyki , których się nauczyli, i którzy patrzą z góry na te pierwsze.


„przepaść kulturowa między programistami CS i nie-CS. Programiści naukowi zwykle uczą się złych nawyków w Fortran i patrzą z góry na programistów CS i złe nawyki, których zostali nauczeni, i którzy patrzą z góry na te pierwsze”. Częściowo po prostu koncentrują się na różnych aspektach problemu. Fortran oznacza FORMula TRANslation i jest dość wydajny w tłumaczeniu formuł matematycznych na kod. Do tego, co zwykle robią rodzaje programowania CS, inne języki są lepsze.
Omega Centauri

1
@Omega: Masz rację. Ludzie uczeni w Fortranie zwykle nie mają pojęcia o formatowaniu, nie znoszą „niejawnego braku” i łączą kod razem, ponieważ nadal zajmują się 72-znakowymi liniami i myślą, że tworzenie zrozumiałego kodu jest dla wimps. Ludzie uczeni przez CS tworzą piramidy potworów klas splecionych z polimorfizmami, powiadomieniami i abstrakcjami, gdy coś prostego by wykonało zadanie. Zasługują na siebie :)
Mike Dunlavey

7
cytat kiedyś „fizycy są rozwiązywaniu problemów na wczorajsze Tomorrows sprzętu - podczas gdy faceci CS są rozwiązywaniu problemów wczoraj na sprzęcie jutra”
Marcina, Beckett

@Martin: Myślę, że może gdzieś to słyszałem. To z pewnością brzmi prawdziwie.
Mike Dunlavey

Martin: Tak więc, faceci od sprzętu są najbardziej wydajni :)
Dhaivat Pandya

2

Zasadniczo wszystkie programy, które wykonują faktyczną pracę przy łamaniu liczb, są nadal FORTRANEM (stare blas, lapack, arnoldi itp. Są nadal używane) ... Jednak jeśli chodzi o strukturę wyższego poziomu ... ludzie coraz częściej używają C ++.

Złożoność symulacji wiąże się z ogromnym kodem, a pisanie jednego z nich przynosi wiele korzyści. Również zastosowane koncepcje stały się bardzo złożone. Reprezentowanie tych informacji za pomocą FORTRAN to prawie szaleństwo. Właśnie tam wkracza C ++, ponieważ z natury wspiera projektowanie obiektowe. Jednak polimorfizm w czasie wykonywania jest rzadko preferowany. Zamiast tego ludzie prawie zawsze używają polimorfizmu statycznego (który jest implementowany w C ++ z szablonowym meta-programowaniem)

Ponadto, teraz kompilatory są naprawdę dobre, dlatego wiele kompilacji pozostawia się kompilatorom.


1

Istnieją dwa rodzaje problemów, które należy rozwiązać w aplikacjach HPC: jednym z nich jest sam kryzys, a drugim zarządzanie obliczeniami. Do pierwszego zwykle podchodzi się z kodem napisanym w Fortran, C lub C ++ ze względu na szybkość i fakt, że istnieje już wiele algorytmów naukowych napisanych w tych językach. Sterowanie obliczeniami jest wygodniej realizowane w językach wyższego poziomu. Python jest językiem „kleju” do obsługi logiki aplikacji i rozszerzeń wywołań zaimplementowanych w językach kompilowanych. Java jest często używana w projektach, w których kluczowe jest zarządzanie siecią i przetwarzaniem rozproszonym.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.