GCC automatycznie zoptymalizuje kod pod kątem wielowątkowości
- Dodano: 11 marca 2009
- Wprowadził: mith
- Komentarze: 75
W niedługim czasie zbiór wolnych kompilatorów, znany pod nazwą GCC, zyska możliwość automatycznej optymalizacji kodu, by ten wykonywał się wielowątkowo i wykorzystywał lepiej procesory wielordzeniowe.
Pracownik IBM-a, Razya Ladelsky, nakreślił plany wprowadzenia tej bardzo przydatnej funkcjonalności. W osiągnięciu tego pomóc ma połączenie frameworka Graphite z nadchodzącym wydaniem GCC w wersji 4.4. Graphite umożliwia zaawansowaną optymalizację pętli, bazującą na modelu polihedralnym (gwiaździstym). W przyszłości zintegrowane z nim ma zostać narzędzie autopar, będące generatorem kodu wielowątkowego, bazującym na GOMP-ie. Warto dodać, że GOMP jest projektem GNU, implementującym stworzone przez Suna OpenMP, czyli API służące do łatwego pisania aplikacji wielowątkowych.
Cała ta masa karkołomnych zabiegów* ma na celu umożliwienie kompilatorowi GCC dokonania automatycznej optymalizacji części pętli, by te wykonywały się równolegle. Powinno to przynieść zysk wydajności na maszynach wielordzeniowych i poprawić wykorzystanie drzemiącej w nich mocy, której większość wciąż niestety się marnuje.
*O których niełatwo nawet po polsku napisać
Więcej informacji: http://www.phoronix.com/scan.php?page=ne...&px=NzEzNA
Znalazłeś literówkę? Zgłoś ją używając formularza!
Jeśli uważasz, że ten nius jest nieobiektywny, przedstawia nieprawdziwe wydarzenie, jest spamem lub nie spełnia standardów serwisu, napisz raport.
Niusy na podobny temat:
Komentarze są prywatnymi opiniami dodających je osób. Prosimy o zachowanie kultury wypowiedzi. Komentarze obraźliwe oraz obniżające poziom serwisu będą usuwane. Więcej w regulaminie komentowania.
75 komentarzy
Wszystkie autorskie niusy w serwisie publikowane są na licencji Creative Commons Uznanie autorstwa 2.5 Polska.


szkoda, że nie ma żadnych konkretnych dat, bo "w niedługim czasie" to bardzo subiektywne odczucie i dla każdego znaczy co innego.
Być może wszystko to odnosi się do wydania 4.4, ale z tekstu, na którym bazowałem nic takiego nie wynika. A snucia domysłów na siebie brać nie zamierzam
Choć chciałbym, żeby to było jak najszybciej zrobione.
Myślałem, że gcc 4.4 jest w fazie zamrożenia. W każdym razie ma być jedną z nowości zapowiadanych dla Fedory 11.
Szkoda, że zapomnieli o dokończeniu implementacji C99…
"której większość wciąż niestety się marnuje" – jakoś tego nie widzę. Jeszcze nie miałem pod linuksem sytuacji żeby jeden rdzeń zdychał, a drugi się nudził. Nie wiem, może po prostu wszystko czego używam i mocno obciąża procesor jest już wielowątkowe. A może mam za mało rdzeni. ;P
Ja mam procesor z dwoma li tylko rdzeniami. W tym apleciku gnomowym, do podglądania częstotliwości mam ustawione "ondemand" i wiesz co? Zwykle oba rdzenie kręcą się z połową prędkości, a obok network-monitor pokazuje na wykresiku, że i tak nie są specjalnie obciążone
Choć oczywiście można im dać trochę popalić, włączając dwie maszyny wirtualne.
mi najczęściej procek chodzi na 1 GHz, a nominalnie mam 2,6 pewnie gdyby dało się zmniejszyć do 800 to by chodził na 800.
Nie, po prostu system rozdziela procesy między procesory i/lub rdzenie. Problemem jest zrównoleglanie pojedynczego procesu. W przypadku np. wydajnych serwerów najwydajniejsza jest architektura "asynchroniczne I/O + wątek/proces per CPU".
Nie do końca rozumiem natomiast, jak to rozszerzenie ma działać – proces będzie implicite uruchamiał dodatkowe wątki? Chyba trzeba sięgnąć do źródeł – newsa, nie kompilatora
Poczytaj sobie o OpenMP, powinno pomóc
Nie wiem, ale już wcześniej do GCC miały być włączone rozszerzenia do wykonywania operacji wielordzeniowych. Instrukcje miały chyba dotyczyć pre procesora i chodziło chyba o jakieś mutex-y(nie jestem dobry w dziedzinie systemów operacyjnych, więc wybaczcie). Wygląda więc na to, że jak najbardziej chodzi o wielowątkowość czy wielowarstwowość aplikacji.
Czy taka funkcjonalność występuje w innych kompilatorach. Jeśli tak to w jakich i czy to faktycznie tak cudownie działa, że zwykły kod działa wielowątkowo.
Pisania wielowątkowego raczej to nie zastąpi.
A to raczej rzecz pewna. Ale jeśli pozwoli zyskać mierzalny przyrost wydajności, to czemu nie?
Wiadomo mi, że taką funkcjonalnością swoich kompilatorów Sun przechwalał się już 10 lat temu na okoliczność wieloprocesorowego serwera "E10K starfire" (podkreślając że jego "superkompilator" pomaga wykorzystać moc onego systemu). A jak to działało i czy rzeczywiście było użyteczne… to osobna historia.
jesli chodzi o implicit parallelism czyli automatyczne zrownoleglanie przez kompilator obliczen pozbawionych efektow ubocznych, bez ingerencji programisty – mialy to na pewno implementacje jezyka sisal na maszyny firm cray i dec, niemal cwierc miliarda lat temu
jesli chodzi o semi-implicit parallelism, czyli "automatyczne" zrownoleglanie obliczen specjalnie oznaczonych przez programiste lub wykonywanych, za pomoca funkcji oznaczonych przez programiste jako pozbawione efektow ubocznych – takie cos powinny miec implementacje jezyka high performance fortran (ale nie wiem czy jakies istnieja
). ma rowniez kompilator jezyka haskell – ghc w wersji 6.10.1. mialy rowniez jezyki concurrent clean i oz – ale w przypadku obu nie wyszlo to z fazy akademickich eksperymentow.
nie wiem jak w przypadku kompilatorow c i c++ – te jezyki sa dla mnie dosc malo ciekawe…
W C i C++ półautomatem jest OpenMP który znajdziesz w takich kompilatorach jak gcc, icc, msvc – np. żeby for rozdzielał się na wątki to przed nim dajesz "#pragma omp parallel for"
@wojtek46_2: Oczywiscie, chociazby w SunPRO.
*szybkie guglanko*
Wedlug http://www.springerlink.com/index/207353n9701x760… SunPRO mialo to juz w roku 1999. Wedlug http://sc.tamu.edu/help/power/powerlearn/g-parall… MIPSpro mialo to w 1998. Wedlug http://www.dell.com/downloads/global/power/ps3q07… kompilator Intela tez to od ladnych paru lat ma.
Dobra wiadomość, choć przyjazność OpenMP pozwala samemu z łatwością wyposażyć program w obsługę wielu wątków.
Takie niefachowe pytanie. Obecnie używa się bibliotek w rodzaju pthreads, by zapewnić wielowątkowość. Używanie automatycznej optymalizacji eliminuje tę konieczność, pokrywa się z nią czy uzupełnia?
Raczej uzupełnia. Nic nie zastąpi dobrze zaprojektowanego algorytmu równoległego, natomiast sam kompilator może np. dodać szeregowanie iteracji pętli for.
Nie jestem wielkim ekspertem w tej dziedzinie ale z tego co wiem to w linux jest mapowanie watkow 1:N. Czyli dla jednego procesu jadra moze byc utworzonych wiele watkow ale w przestrzeni uzytkownika. Jadro systemu nie wie tak naprawde ile watkow posiada dany proces wiec nie potrafi ich wykonywac na 2 procesorach/rdzeniach bo nie wie o ich istnieniu.
Moje pytanie jest nastepujace. Czy te wszystkie optymalizacje wielowatkowe maja na celu stworzenie nowych procesow i im przydzielenie watkow? Czy moze chodzi o optymalizacje wielowatkowe ale w sensie sprzetowym (np tak jak w Itanium)?
Nie. Tu chodzi o prosty mechanizm. Chcemy wykonać coś takiego:
for (i=0; i
heh… wycielo mi wieksza czesc komentarza…
for ( i=0; i mniejsze od n; i++ )
doSth(tablica[i]);
Jesli funkcja doSth() nie zmienia niczego poza swoim parametrem, to dla wszystkich elementow tablicy moze zostac wykonana rownolegle. Jesli jednak zalezy od innych parametrow, czy tez moze od wartosci innych elementow tablicy, wtedy dostaniemy miliard bardzo trudnych do wykrycia błędów.
Tyle teoria, a w praktyce dochodzą pewne problemy:
1. Jeśli pętla wykonuje krótkie zadanie, mało iteracji lub iteracje proste i krótkie, koszt odpalenia i zakończenia kilku wątków może być nieporównywalnie większy niż koszt wykonania całości jednowątkowo.
2. Jeśli pętla wykonuje dużo iteracji na dużej strukturze danych, która nie mieści się w cache procesora, to na 100% wąskim gardłem jest transfer pamięć-procesor i nic na wykonaniu równoległym się nie zyska. Ba, nawet jeśli mieści się w cache, ale nie jest załadowana – też niewiele pomoże.
3. Jeśli pętla jest kosztowna, to b. często jej iteracje są na tyle złożone, że b. trudno automatycznie stwierdzić, że poszczególne iteracje są od siebie niezależne. Kompilator musi się upewnić że każda iteracja operuje na rozłącznych zbiorach danych (z wyjątkiem danych tylko czytanych przez wszystkie iteracje).
4. Przy statycznej kompilacji bardzo często nie da się stwierdzić ile iteracji średnio wykonuje pętla. Stąd taka technika miałaby już większy sens w maszynach wirtualnych lub przy kompilacji sterowanej profilem.
Generalnie dość trudno znaleźć przypadki, gdzie te przeszkody nie zachodzą, stąd jestem nieco sceptyczny. Więcej już można zyskać rozsądnie wektoryzując pętle na instrukcjach SSE (nie ma narzutu odpalania wątków i synchronizacji) co w gcc na razie też mocno kuleje.
Właśnie. Wektoryzacja kodu jest znacznie łatwiejsza w analizie i implementacji niż automatyczny podział na wątki. Jeśli więc do tej pory gcc ma z wektoryzacją problemy, to jak to będzie wyglądało tym razem?
Też nie jestem ekspertem w dziedzinie. Wydaje mi się jednak, że masz trochę przestarzałe informacje. Jądro obecnie – o ile mnie pamięć nie myli – obsługuje wielowątkowość. Inną kwestią jest to, że wielowątkowość z poziomu jądra działa mniej wydajnie od tej dostarczanej przez pthreads. Jeżeli jednak sytuacja się odwróci, to nic nie stoi na przeszkodzie chyba, by pthreads wykorzystywało wielowątkowość jądra(opóźnienia spowodowane wywołaniem bramki do procedury są obecnie bardzo niewielkie).
To są zupełnie różne mechanizmy. Zwykle program ma wiele wątków, z których każdy robi co innego. W omawianym w artykule przypadku ( i w OpenMP ) chodzi o to, żeby automatycznie generować mikrowątki w przypadku, kiedy chcemy wywołać jakąś funkcję dla każdego elementu w tablicy. Przy czym to zwykle są bardzo szczególne przypadki, więc nie ma się czym podniecać.
OpenMP zapewnia tą samą funkcjonalność od dawna. Dodatkowo, często nie można zastosować takiego wątkowania przez efekty uboczne działania funkcji. Kompilator nie może automatycznie rozpoznać takich rzeczy, dlatego w OpenMP są specjalne instrukcje do zarządzania takimi przypadkami.
Tą samą, nie tą samą… GCC zrobi to w ramach optymalizacji bez dodatkowego wkładu intelektualnego ze strony programisty (czyt. bez dodatkowych #pragma …)
.
Jak mi automatycznie zrównolegli taki BANALNY kod liczący silnię, to chylę czoła:
int x = 1;
for (int i = 2; i mniejsze równe k; i++)
x *= i;
Jak to było w prawach Murphyego? Proste problemy okazują się trudne, trudne problemy okazują się niemożliwe do rozwiązania…
Intencją autorów gcc jest optymalizacja bardzo prostych pętel, dających się łatwo zrównoleglać. Mój komentarz odnosił się do tego, że używając OpenMP człowiek musiałby dodać sobie roboty, podczas gdy gcc zrobi to sam.
Analiza języka naturalnego jest trudną rzeczą [dla maszyn także].
Przy optymalizacji bardzo prostych pętli odpalanie wątków raczej dużo nie pomoże.
1. Żeby narzut na wątki się opłacał, pętla musi wykonywać się istotną ilość czasu (przy prostej pętli sumującej 10 intów się nie opłaci).
2. Jesli do tego stawiasz warunek, że pętla ma być PROSTA, to jedyny sposób na osiągnięcie tego, to zapewnienie dużej liczby iteracji.
3. A teraz dołóż do tego warunek o niezależności iteracji od siebie i dostajesz, że ilość danych przetwarzanych tą pętlą musi być co najmniej proporcjponalna do liczby iteracji.
4. Przy dużej ilości danych, nie zmieszczą się one w cache'u i wszystko utknie na transferach pamięć-procesor, nieważne czy sekwencyjnie czy równolegle.
Opłaca się w ten sposób zrównoleglać właśnie jedynie złożone pętle (np. wywołujące kosztowną funkcję) i po to są pragmy w OpenMP. Proste pętle się zrównolegla przez dużo lżejsze SSE.
hmm a jak kolega królik ma zamiar tak prosty przykład zrównoleglić?
Przeca tu jest tylko jedna instrukcja.
Oczywiście bez użycia twierdzeń matematycznych?
wlasnie po to jest #pragma w OpenMP, zeby pokazac gdzie i jak kompilator moze bezpiecznie zrównoleglac, a gdzie nie powinien sie dotykac.
@ak47: wlasnie przyklad królika pokazywał, że niektórych rzeczy nie da się zrównoleglić.
A dlaczego bez użycia twierdzeń matematycznych? Każda optymalizacja kodu opiera się na twierdzeniach matematycznych. Ten przypadek do ręcznego zrównoleglenia jest banalny, więc zakładam, że kompilator też powinien potrafić.
Jeśli tylko łączności i przemienności mnożenia (no, nawet bez przemienności
) nie nazwiemy twierdzeniem matematycznym, to ten kod da się zrównoleglić i bez używania twierdzeń
. Swoją drogą – programiści kompilatorów może jakoś wysiedzieliby automat, który i takim kodom dawałby radę.
@Królik, ak47: to automatyczne dzielenie na wątki będzie się z pewnością odbywać tylko na pętlach które nie korzystają wartości obliczanych w tej poprzednich iteracjach – bo to rozwaliłoby algorytm – cała zabawa z tą optymalizacją będzie wyglądać pewnie tak, że sprawdzi za programistę czy można tą funkcję rozdzielić, i użyje openMP jeśli tak. Ta optymalizacja nie ma zastąpić programisty, więc na wykrywanie co programista miał na myśli pisząc algorytm nie równoległy i zamieniać go na lepszy ;p
Problem w przykładowym kodzie polega na sekcji krytycznej =P. Nie da się go zrównoleglić, bo wartość x musi być za każdym razem odczytana, przemnożona i zapisana. W tym czasie nie może dojść do odczytu tej wartości przez drugi proces, bo mnożenie zostanie zgubione wraz z zapisem wyniku operacji mnożenia drugiego procesu. Tak, więc uruchamianie tej pętli na paru wątkach mija się z celem, gdyż wykonywane i tak będą sekwencyjnie.
Jedyne co uzyskamy to dodatkowy narzut czasowy związany z zarządzaniem wątkami i operacjami na mutex'ach.
Oczywiście, można podzielić fory na dwa osobne (jeden pracujący na liczbach parzystych, drugi nieparzystych lub z podzielić je na dwa rozłączne równoliczne zakresy) wykonywane na różnych rdzeniach i różnych zmiennych, a następnie uzyskane wyniki pomnożyć. Ale to już nie jest ten sam program =)
NDyA: Druga część Twojej wypowiedzi, to ten sam program w wersji współbieżnej
.
kj: Tak, ale z punktu widzenia kompilatora to już nie jest ten sam program, bo operowałby na dwóch zmiennych zamiast jednej. Gratulacje dla osoby, która dodałaby wsparcie dla takiego zrównoleglania programów w GCC.
W przypadku takiego jednego inta, to jeszcze nie jest problem, ale gdyby tam zamiast inta była tablica zajmująca więcej niż 2 MB (taka sobie przykładowa wartość) to zwiększamy ilość zajmowanego miejsca w pamięci i dodajemy narzut czasowy związany z kopiowaniem tablicy =P (wypełnienie jej samymi jedynkami też może trochę czasu kosztować).
W wyżej wymienionej sytuacji trzeba przeanalizować, czy operacje współbieżne pozwalają realnie zaoszczędzić czas (zysk rzędu 2-3 % raczej nie jest warty świeczki, a blokuje możliwość dla systemu wykorzystywania kolejnego rdzenia – no może w bazach danych taki zysk ma jeszcze sens). Taką kalkulację przeprowadzić potrafi jedynie człowiek, bo będzie ją analizować na konkretnych przykładach. Żaden algorytm Ci tego nie policzy.
@NDyA: właśnie to chciałem pokazać. Dla programisty przerobienie tego kodu nie jest trudne (wprowadzenie pomocniczych zmiennych i dodanie mnożenia na końcu), natomiast dla automatu problem łatwy nie jest. A to tylko głupia silnia. Większość pętli zawiera dużo bardziej złożone obliczenia niż x *= i; – np. inne pętle. Stąd mój sceptyzm odnośnie skuteczności tego typu automatów. Naprawde lepiej, żeby twórcy GCC energię przeznaczyli na lepszą wektoryzację SSE, czy sensowniejsze komunikaty o błędach.
Dla programisty również może być trudne =). Dla jakiegoś algorytmu zrównoleglania śmiem twierdzić, że jest to niewykonalne (przy założeniach, że kompilator nie ma alokować dodatkowych zmiennych jest to na pewno niewykonalne).
Kwestia spojrzenia na problem. W aplikacjach na desktop takie optymalizacje raczej nie są aż tak potrzebne. Bardziej opłaca się rozdzielać wątkami warstwę obliczeniową od interfejsu. W ten sposób możemy łatwo zagwarantować responsywność interfejsu (w czasie długotrwałych obliczeń użytkownik może przeglądać np. poprzednie wyniki i raporty). Na jednym jednordzeniowym procku taka aplikacja i tak będzie się ciąć (i wiele nie pomogą priorytety procesów – aplikacja będzie działała wolniej =P), ale na dwu już uzyskamy zamierzony efekt.
Wszystko kwestia spojrzenia na problem. Niedługo zresztą będzie trzeba projektować programy, aby mogły korzystać z n rdzeni, a nie tylko dwóch =P.
Po pierwsze: wątki są rozpoznawalne przez jądro – stąd nawet nazywanie wątków w literaturze fachowej lekkimi procesami. Po drugie – nic nie zastąpi własnoręcznego pisania kodu wielowątkowego z użyciem pthread, ale… jeśli masz pętle która dajmy na to przeskakuje przez ileś tam set elementowy wektor. Przy każdej iteracji wykonujesz jakieś super skomplikowane operacje na obiektach znajdujących się w środku, a kolejność elementów w wektorze (a więc i wykonywanych instrukcji) nie ma znaczenia.
Dzisiaj możesz to osiągnąć tworząc przy każdym obrocie pętli nowy wątek, lecieć dalej, a na koniec samemu zająć się synchronizacją tego bajzlu. Po to tworzy się takie dziwaczne optymalizacje w kompilatorach by zaoszczędzić programistom nieco pracy. Właściwie to skok taki jak przejście z for(;;) na foreach(coś in tam) – niby przydatne, ale można się obejść bez tego (a może jednak nie skoro w planowanej aktualizacji standardu c++ ma się znaleźć owa "nowa" pętla).
"a więc i wykonywanych instrukcji" trochę się zapędziłem pisząc to "na spontanie" – rzecz jasna chodzi o kolejność iteracji pętli – tak dla ścisłości (-:
Wystarczy "tylko" rozpoznać, ze kolejność iteracji nie ma znaczenia i że mogą być zrównoleglone. Jak podałem w przykładzie wyżej, nawet dla tak prostego kodu jak liczenie silni, nie jest to proste zadanie. Poza tym w C i C++ to już w ogóle masakra, bo wywołanie funkcji z innego modułu wewnątrz pętli kładzie na łopatki całą optymalizację – po prostu kompilator nie ma dostępu do jej treści. Czyli – ograniczamy się do przypadków wywołań w ramach jednej jednostki translacji, korzystających z całkowicie rozłącznych danych, nie korzystających nigdzie po drodze z funkcji systemowych, w tym synchronizacji oraz nie zapisujących zmiennych oznaczonych jako volatile. Zostaje pewnie nie więcej niż jakieś 1% przypadków. Nie wiem, czy gra jest warta świeczki.
Ale może niech zrobią. Rok później M$ ściągnie to do .NETa, a Sun do JVM, gdzie tego typu optymalizacja ma dużo większą rację bytu. Choć skoro do tej pory tego nie zrobili (zwłaszcza Sun, który ma już taką technologię), to znaczy, że gra nie jest warta świeczki.
A, dodam jeszcze, że w przypadku użycia wskaźników, sprawdzenie czy 2 wskaźniki z 2 różnych obiektów nie wskazują przypadkiem na te same dane na podstawie samej analizy statycznej kodu graniczy z cudem. Czyli do listy restrykcji dopisujemy jeszcze wskaźniki, z wyjątkiem trywialnych sytuacji.
Królik: wybacz stary, ale z tą silnią to totalnie nietrafiony pomysł. Jest to idealny przykład pętli w której kolejność iteracji MA znaczenie.
Ale weźmy sobie na warsztat moją inżynierkę. Mam wektor z obiektem typu cPomiar i drugi przygotowany pod wypełnienie Point-ami. Z grubsza chodzi o policzenie środka ciężkości na podstawie sił z trzech czujników nacisku. Każdy element pierwszego wektora nie ma totalnie żadnego wpływu na resztę – grunt to zapisać w wektorze pozycje x|y w takiej samej kolejności jak były zapisane pomiary sił nacisku. W całym kodzie wystarczy więc wyrzucić po każdym zastosowaniu magicznego wzoru do przeliczania sił na pozycję, zamiast nazwa_wektorka.add(tymczas), trzeba utworzyć od razu wektor o takiej samej długości co ten z pomiarami, a potem po obliczeniach pamiętać indeksy i pod tymi indeksami robić nazwa_wektora[index] = tymczas.
Właśnie sobie uświadomiłem że mógł bym przyspieszyć nieco swoją inż. i to nie czekając na tą magiczną poprawkę w gcc, ale są dwie drobnostki: 1 – napisałem to w c#(wiem wstyd, ale chcieli pod windowsa), 2 – to itak wykonuje się w 3 sekundy dla 1MB danych i jest używane raz na ruski rok – nie ma sensu tracić czasu na coś takiego (co nie zmienia faktu że ucieszył bym się gdyby takie coś "samo" mi się zrobiło).
@wit3k: wlasnie o to w przykladzie z silnia chodzilo – kolejnosc iteracji ma znaczenie, ale jak kompilator ma to stwierdzic? Musi sprawdzic, ze zmienna x jest wykorzystywana w wielu iteracjach. Musi tez sprawdzic milion innych przypadkow, o ktorych wspomniał Królik – to powoduje, że czas kompilacji wydłuża się bardzo, a efektów nie ma prawie żadnych.
W przypadku silni jest właśnie bardzo trafiony. Z pozoru patrząc na kod kolejność ma znaczenie, ale dobry programista bez problemu zauważy, że mnożenie jest ŁĄCZNE i można kod rozbić ładnie na więcej wątków. Kompilator… no, musiałby być dość inteligentny.
Co do tego, że czasem ta optymalizacja będzie działać, no zgadzam się, będą takie przypadki. Jednak w praktyce i tak Ty jako programista będziesz musiał najpierw poukładać kod tak, żeby ułatwić kompilatorowi zadanie. Wystarczy jedno wywołanie funkcji z innej jednostki translacji albo zapis pamięci poprzez wskaźnik i ta technika leży.
No fakt mnożenie jest łączne przy czym – jak ja bym robił takie coś to jako leniwy programista na początek zostawił bym tylko takie pętle do optymalizacji które nie zapisują wielokrotnie do tej samej zmienne i … tutaj sugestia kolegi – zapisywane wyniki są co najwyżej poddawane mnożeniu. Właściwie to wielki pokłon dla mózgów zajmujących się takimi rzeczami – jeszcze tak sobie myślę że kompilator mógł by "łączyć" działanie pętli.
Dajmy na to taką bazdkę danych która najpierw – przeszukuje, a potem wysyła przez socket krotki pasujące do zapytania. Można by rozpoznać zależność między takimi dwiema pętlami i działać z wyprzedzeniem – choć tutaj to też właściwie z całą pewnością po prostu jest zmobilizować mózg twórcy DB – niech i on nieco popracuje i zrobi sobie 2gi wątek i np. machnie semafor podnoszony przy evencie (trzeba to połączyć z observerem).
@wit3k: co do baz danych to zupełnie inaczej się robi. Tworzy się iteratory, które mają możliwość wykonywania potokowo, czyli uzyskuje się efekt jaki opisałeś mimo wykonywania sekwencyjnego. Odpalanie wielu wątków na przetwarzanie jednego zapytania nie ma zwykle sensu, bo nie bardzo jest jak takie wątki kontrolować, a dosyć mocno konkurowałyby o zasoby i mogłoby dojść np. do szmotania. Jeśli już, to w przypadku, gdy dane znajdują się na więcej niż jednym fizycznym dysku, ale tu też raczej preferencja jest w kierunku asynchronicznego we/wy niż odpalania wątków (np. Oracle czy DB/2 bez aio w kernelu nie ruszy). Ba, odpalanie zbyt wielu wątków _w ogóle_ dla całej instancji też nie jest dobre – zwykle odpala się tylko tyle wątków aktywnych ile jest rdzeni (pozostałe są celowo wstrzymywane). I kontroluje to RDBMS, a nie OS, bo OS ma za mało informacji o przewidywanym zapotrzebowaniu poszczególnych wątków na zasoby.
Jest wiele elementów języka które da się zastąpić innymi (np. "switch case" da się zastąpić szeregiem instrukcji if). Nowe elementy języka nie muszą koniecznie wprowadzać nowych możliwości, wystarczy, że ułatwią prace programistom.
Nowa pętla foreach jest zarąbista. Szkoda tylko, że pewnie prędzej powstaną natywne kompilatory Rubyego niż kompilatory C++ dogonią standard C++0x
Dogonią jak standard zostanie oficjalnie zatwierdzony – jak na razie nie ma formalnie czegoś takiego jak C++0x
To tym gorzej.
Popatrz – a gcc już implementuje pewne części standardu przed jego zatwierdzeniem. Być może implementacja będzie przed standardem
Cały ten news (i ten opis na Phoronix) sam sobie przeczy. Albo to GCC będzie zrównoleglać bez pomocy programisty (co jak już wyżej pokazano jest zadaniem w ogólnym przypadku dość karkołomnym i sprawia duże problemy), albo będzie się wspomagać OpenMP co ma już miejsce od GCC 4.3, może tylko GOMP jeszcze nie jest tak skuteczny jak by mógł być.
Czyli krótko mówiąc tabloidowy tytuł opisujący nowe optymalizacje w GOMP-ie, nic więcej.
I na koniec, gdzie autor znalazł informację, że OpenMP zostało stworzone przez Sun-a, bo tutaj: http://openmp.org/wp/about-openmp/ nie ma o tym ani słowa, a Sun jest tylko jedną ze zrzeszonych organizacji.
gcc ma zrownoleglac bez pomocy programisty, w oparciu o statyczna analize petli wykonana przez framework graphite.
nieprawda. graphite odpowiada za statyczna analize i oparte na niej przeksztalcenia (optymalizacje) petli. jest odpowiednikiem przebiegu autopar (i innych). artykul nie jest o gompie, tylko o graphite…
No to dlaczego integrują to z GOMP-em? Może dlatego, że statyczna analiza _pętli_ to trochę za mało, żeby móc mówić o wątkowaniu…
gcc – to coś co sie programistą microsoftu śni po nocach.
Wątpię, aby gcc miał jakiekolwiek sny. To kompilator.
GCC śni się ludziom z MS, a nie śni o czymś ;p
a mnie się śni słownik dla każdego za darmo ;]
Raczej analizator gramatyczny. „Programistą” jest (niestety) poprawnym słowem w języku polskim. Z „sie” już trochę gorzej, fakt.
"Programistą" a "programistom" to jednak różnica – liczby i przypadku.
@szczerydobolu: Raczej cos, co wspominaja przy piwie przy pogawedkach w rodzaju 'a wiecie, ze GCC dorobilo sie w koncu *tu wstaw dowolny ficzer*? Stefan, kiedy to zaimplementowalismy w VC, w 1998?' ;->
Trasz, jak dobrze wiesz nad Visual C++ pracuje aktualnie 'aż' jedna osoba, kompilator (CL) jest od kilku wydań praktycznie ten sam. Pracuję na VC++ i sobie ten 'sprzęt' chwalę, ale faktem jest, że GCCLLVM rozwijają się znacznie szybciej i na chwilę obecną lepiej optymalizują kod. Niestety ale CL jak i sam Visual nadal (2008 sp1) ma kupę bugów, które już w becie Visuala 2005 były obecne – jeszcze nie spotkałem się z tym aby konkurencyjne kompilatory (w tym Intela) wywaliły internal error i zdechły podczas próby kompilacji haxowatego bądź niepoprawnego kodu.
Znaczy np. implementacji części C++0x. No właśnie — kiedy? 2012? Czy może działającego PGO? Też 2012?
@bies: PGO bylo w Visual Studio wczesniej niz w GCC:
http://msdn.microsoft.com/en-us/library/aa289170….
A co do C++0x – tego jeszcze nie ma, wiec co maja implementowac?
A w druga strone – kiedy GCC nauczy sie optymalizowac produkowane binarki w taki sposob, aby nie porazaly absurdem kazdego, kto jako tako rozumie asembler x86? Przyklad jakis czas temu przytaczalem.
Kod nie ma być ładny, ma być szybki. Reverse engineer i tak sobie z analizą poradzi a innym wara od binarki. Faktem jest, że Visualowy CL generuje bardzo ładny kod, niestety wolniejszy mimo kilku rozwiązań, których GCC nie oferuje.
Zapomniałbym – trasz, coś s`trasznie wybiórczo podchodzisz do informacji z MSDN-u, Visual C++ 2008 SP1 implementuje fragmenty nowej biblioteki standardowej C++0x… a podobno tego jeszcze nie ma.
@LV: Tyle, ze kod w wykonaniu GCC jest nie tylko brzydki, ale takze powolny. Popatrz na porownania wydajnosci tego kodu z kodem generowanym przez LLVM. Albo zastanow sie, dlaczego nikt nie stosuje GCC tam, gdzie wydajnosc jest istotna – w HPC albo w grach komputerowych.
Tak, tak, LLVM często jest sporo szybsze od GCC, faktem jest, że CL jest wolniejszy od obu. Fakt, w grach stosuje się czasem jeszcze gorsze kompilatory Borlanda – krytycznym czynnikiem kształtującym wydajność jest algorytm, nie te kilka procent różnic pomiędzy kompilatorami.
@LV: Ktora gra – z tych 'duzych' – jest kompilowana Borlandem?
A co do kilku procent – kazdy FPS sie liczy, wiec kompiluja albo VS, albo Intelem.
Sorry, ale co wspólnego mają wielościany gwiaździste z optymalizacją pętli?
optymalizacje wielokrotnie zagniezdzonych petli mozna sprowadzic, jak wiele innych problemow optymalizacyjnych, do problemu programowania liniowego. czyli minimalizacji lub maksymalizacji liniowej funkcji celu przy rowniez liniowych warunkach ograniczajacych. a te ograniczenia definiuja jakis parametryczny zbior wieloscienny – geometrycznie wielotop, czyli uogolnienie wieloscianu. stad taka nazwa-skojarzenie.