2010-06-21 11 views
5

Przepraszamy za niewyraźne pytanie z tematu, ale pracuję nad niektórymi akademickimi procedurami przetwarzania wideo. Algorytmy są napisane w MATLAB-ie, i chociaż jest to dobre dla celów programistycznych, to przetwarza wideo o wartości około 60spf lub około 0,0166 fps. Nie trzeba dodawać, że to nie wystarczy na dema i takie, więc moja letnia praca polega na przekształceniu rutyny w coś, co będzie działać drastycznie szybciej.Jakie jest najlepsze rozwiązanie dla kłopotliwego problemu równoległego?

Napisałem najwolniejszą część kodu dla CUDA, rozwiązania GPGPU nvidii. Jednak istnieje również duża część kodu, która wydaje się być lepiej wykonana na procesorze, ponieważ jest względnie szeregowa. Problem polega na tym, że maszyna, którą dostałem, ma 2 procesory Xeon, z 8 rdzeniami logicznymi, i wydaje się wstydem zawężać kod GPU przez kodowanie tylko dla pojedynczego rdzenia. Proces konwersji wideo działa tak, że każda klatka nie zależy od innych klatek, więc pomyślałem, że najlepiej będzie jakaś asynchroniczna kolejka/strumień.

Oto kłamstwo moje pytanie: jaki byłby najlepszy sposób na osiągnięcie tego typu równoległości z najlepszym stosunkiem wysiłku do zwiększenia wydajności?

Niektóre z rozwiązań, na które patrzyłem to OpenMP, .NET TPL i tylko proste pthreads.

Mam tylko podstawową ekspozycję na programowanie asynchroniczne, więc wolałbym raczej korzystać z biblioteki lub czegoś, niż bawić się z muteksami i barierami i strzelać sobie w stopy kilka razy. Nie mam nic przeciwko uczeniu się, ponieważ jest to jeden z moich celów na lato, ale jednocześnie równoległość to ciężko. Jednakże, jeśli różnica prędkości jest rzeczywiście bardzo zauważalna, jestem skłonny wyciągnąć włosy na kilka tygodni. : P

Z góry dziękuję.

+0

Jeśli możesz zepsuć problem na wiele części, nad którymi można pracować bez zakłóceń (z dobrze określonymi punktami synchronizacji), wówczas "biblioteka" powinna być po prostu cukrem ... jednym prostym sposobem jest użycie pula wątków, równoległe kolejki (jedna dla danych wejściowych, druga dla danych wyjściowych) i tylko obiekty/dane dostępu, które ten wątek "posiada" (to można powiększyć do niezmiennych struktur zewnętrznych). –

Odpowiedz

3

Jeśli celem jest maksymalizacja wysiłku, aby uzyskać plon, polecam przeglądanie licencji TPL w .NET. Jest to prawdopodobnie najprostszy sposób wdrożenia tego. W zależności od tego, co robi twój kod, możesz utworzyć potok lub po prostu użyć Parallel.For (lub ForEach) na każdej "ramce".

W związku z tym, jeśli chcesz pozostać przy natywnym, niezarządzanym kodzie, dobrym rozwiązaniem może być nowa wersja Microsoft Parallel Patterns Library lub Intel's Threading Building Blocks. Oba mają podobne konstrukcje do nowej licencji TPL, szczególnie w przypadku paralelizmu danych, co sprawiłoby, że byłoby to dość łatwe do zrównoleglania, o ile "każda klatka nie zależy od innych ramek" pozostaje prawdą.

+0

Pokonaj mnie! Ade Miller miał dobrą rozmowę w TechEd na temat opcji równoległych dostępnych w .Net 4.0: http://www.msteched.com/2010/NorthAmerica/ARC205 – Mathias

+0

PPL wydaje się być dokładnie tym, czego szukałem, dzięki. Jedno pytanie jednak, czy korzystanie z kodu zarządzanego, takiego jak C#, znacznie spowalnia kod, jak np. Moja, gdzie jest to głównie arytmetyczna liczba zmiennoprzecinkowa na dużych tablicach? Lubię bardzo uproszczone środowisko programistyczne, ale przy takich rzeczach jak przetwarzanie wideo, zawsze jestem niezdecydowany z powodu obaw związanych ze zbieraniem śmieci i związanymi z tym kosztami kontroli. Może to być jednak stara paranoja programowania C: \ – Xzhsh

+0

Xzhsh: Osobiście używam C# i kodu zarządzanego do przetwarzania danych naukowych w mojej "pracy na dzień". To bardzo dobrze, ale perf. cechy różnią się od natywnego kodu - więc musisz dostosować swoje myślenie, aby to zrekompensować. Osobiście nie martwiłbym się o to, że GC jest problemem, ale sprawdzanie ograniczeń w zakresie tablicy może spowolnić (może to być wyłączone). Jednak w większości przypadków staranne profilowanie i "dobry" kod zarządzany może prowadzić do kodu, który jest tak szybki (i często szybszy) niż kod natywny. –

1

Moja rada to podejście w sposób stopniowy.

  1. Po pierwsze, udowodnij, że masz funkcjonalną implementację inną niż MATLAB. To nie jest trywialne i, szczerze mówiąc, myślę, że powinieneś zaplanować wydawanie 100% swoich cyklów mózgowych na poprawność, zanim pomyślisz o wydajności.

  2. Podzielenie rozwiązania: udowodnij, że możesz wziąć rutynę, która według ciebie jest oddzielona od reszty implementacji i wyizolować ją syntaktycznie od reszty kodu. Na przykład, jeśli mówisz o znaczniku promieni, możesz wziąć matematykę, która wynika z jednego punktu widzenia, promieniującego pojedynczym pikselem do wspólnego środowiska. Jest to również nietrywialne, ponieważ wymaga myślenia o tym, co jest rzeczywiście powszechne (np. Geometria środowiska, mapy tekstur itp.) I co jest charakterystyczne dla wyjątkowej sytuacji (np. Promień od oka do piksela) . Profilowanie wydajności jest tutaj Twoim przyjacielem.

  3. Zidentyfikować składnię bibliotek lub frameworków, które są zainteresowane, które będą wymagane do równoległego tworzenia wątków/procesów, uruchamiania ich i dołączania do ich wyników po zakończeniu. Uwaga: musisz mieć wzajemne wykluczenie na współdzielonych danych, itp. Na przykład w świecie Java będzie to java.util.concurrency.

  4. Spróbuj utworzyć dwa (tylko dwa) wątki, aby podzielić swoją pracę na pół. Pisz testy porównawcze, które pozwolą Ci zmierzyć początkowe rozwiązanie, rozwiązanie dla N = 2 wątków i sprofilować wyniki.

  5. Tylko wtedy powinieneś pomyśleć o dalszej równoległości.

Jeśli wykonaj kroki jak te, będziesz (a) odnieść sukces w swojej rzeczywistej zadania (port z MATLAB), (b) mieć coś, co działa na niektórych znanych wskaźników wydajności oraz (c) posiada jasne do przodu, jeśli chcesz dalej wykorzystywać możliwości parallizowania.

+0

Dzięki za napiwek Bob! Przesunąłem już procedury do większości C, a paralelizm byłby tylko pomiędzy ramkami, które są całkowicie niezależne. Podoba mi się twoja rada, i na pewno będę o tym pamiętać podczas kolejnego projektu – Xzhsh

+0

@ Xzhsh, FYI, w mojej pracy graficznej najlepszy był równoległość w stosunku do poszczególnych klatek, zamiast przypisywania całej klatki niezależnie do poszczególnych procesorów . Wspólne środowisko silnie motywowało podział pikseli na różne wątki i przyspieszenie obliczeń pojedynczej klatki (w końcu był to raytracer). Wybór podejść jest prawdopodobnie kolejnym dobrym tematem do zbadania w ramach projektu. –

Powiązane problemy