2012-03-25 15 views
8

Im więcej używam Parallel.ForEach i PLINQ w moim kodzie, tym więcej widzę twarzy i recenzji kodu. Więc zastanawiam się, czy istnieje jakikolwiek powód, dla którego NIE używam PLINQ, w ekstremalnych przypadkach, na każdym wyciągu LINQ? Czy środowisko uruchomieniowe może nie być wystarczająco inteligentne, aby rozpocząć odradzanie się tylu wątków (lub zużywających tak wiele wątków z puli wątków), że wydajność aplikacji faktycznie by się pogorszyła, zamiast poprawić? To samo pytanie dotyczy biblioteki równoległej..NET 4 Parallel.ForEach i PLINQ: czy mogą przytłoczyć pulę wątków i zabić wydajność aplikacji?

Rozumiem konsekwencje związane z bezpieczeństwem wątków i narzutami korzystania z wielowątkowości. Rozumiem też, że nie wszystko jest dobre dla równoległości. Zastanawiam się tylko, czy powinienem przestać bronić swoich podejść i po prostu zrezygnować z tych dwóch drobnych rzeczy, ponieważ moi rówieśnicy myślą, że lepiej byłoby zrobić samemu kontrolę wątków zamiast polegać na urządzeniach .NET?

AKTUALIZACJA: należy założyć, że sprzęt jest wystarczająco dobry, aby spełnić wymagania wstępne dotyczące wielowątkowości.

+0

Wierzę, chyba że ręcznie ustawisz plinq używa tylko kilku wątków na podstawie liczby rdzeni, które masz –

+0

@LukeMcGregor: czy wiesz, jakie są wartości domyślne i jak je zmienić? – Schultz9999

Odpowiedz

4

To wszystko sprowadza się do dwóch rzeczy:

  1. Czy dodatkowa praca wymaga się podzielić kolekcję i synchronizować wątki większy niż przyrost wydajności w porównaniu do zwykłego foreach?

  2. Czy wszystkie wątki będą korzystać z zasobu udostępnionego, który stanie się wąskim gardłem?

Przykładem drugim przypadku robi Parallel.ForEach nad wynikami Linq to Sql oświadczeniu. W takim przypadku, jeśli wyniki będą pochodzić z DB bardzo powoli, każdy wątek może spędzać więcej czasu na oczekiwaniu na przetwarzanie danych niż na robieniu czegoś.

Patrz: http://msdn.microsoft.com/en-us/library/dd997392.aspx

+0

Powiedzmy, że mam 1000 klientów, że muszę zastosować jakąś czynność obliczeniową (bez wywoływania db, bez czekania na inne zasoby), czego rezultatem będzie przechowywanie w zsynchronizowanym zbiorze (może to jednak być kara). Napisałem więc Parallel.ForEach (consumer, c => ...) z nadzieją, że będzie to szybsze niż proste foreach. Rozumiem, że bez faktycznego profilowania wyników trudno powiedzieć, czy moje nadzieje są uzasadnione. Ale z naiwnego rozumowania to podejście wydaje się słuszne. – Schultz9999

+0

Wydaje się to słuszne. Ale znowu, musiałbyś rzucić trochę pracy obliczeniowej dla każdego klienta. Na przykład proste obliczenia arytmetyczne nie wystarczą, by uzasadnić równoległość. – Diego

2

Kiedy kopać w tym spektaklu pytania głęboko, myślę, że najlepszą rzeczą do zrobienia jest ... pomiar, pomiar i pomiar. Nawet jeśli ktoś odpowiedziałby, że PLINK jest świetny i zwiększy wydajność twojej aplikacji, czy zaufałbyś temu, nie weryfikując go za pomocą profilowania? Chociaż ogólne odpowiedzi mogą istnieć, nie możesz oszczędzić wysiłku, aby zmierzyć wydajność w twoim przypadku. Ogólna wydajność zależy od tak wielu rzeczy i może być tak, że PLINK pomaga w jednym przypadku, ale nie w drugim.
Moje osobiste doświadczenia z PLINK są takie, że po wysłaniu każdego zapytania LINQ do PLINK czas odpowiedzi jest lepszy, gdy ładunek jest mały i nie ma żadnej różnicy, gdy obciążenie jest w pobliżu jego maksimum. Ale mogę sobie wyobrazić przypadek, w którym PLINK szkodzi ogólnej wydajności pod ogromnym obciążeniem. Muszę to sprawdzić dla twojego konkretnego przypadku.
Cóż ... i jeśli chcesz przekonać inne osoby, że idziesz właściwą drogą, co innego byłoby lepsze niż wyniki pomiarów?

Powiązane problemy