Witam,
Nie wkleję tutaj kodu swojego program, bo jest dość duży i składa się z kilkunastu plików, ale zastanawiam się czemu nie uzyskuję żadnego przyspieszenia w związku z wykorzystaniem wielowątkowości.
Ponieważ nie udostępniam kodu (przedstawię tylko charakter obliczeń) proszę tylko o ogólne wskazówki dotyczące powodów gdzie może wystąpić spowolnienie.
Dla uproszczenia przyjmijmy że mam jedną klasę ze zmiennymi statycznymi i lokalnymi (czyli zwykłymi zmiennymi). Zmienne statyczne są tylko odczytywane, nie ma w klasie żadnych semaforów itd., każdy wątek robi swoje i nie przejmuje się drugim. Program w sumie tylko używa pamięci (mały rozmiar) i wykonuje na niej obliczenia. Wątki tworzę funkcją CreateThread(). Próbowałem z różnymi priorytetami.
I tak:
Po uruchomieniu dwóch instancji programu, w którym w każdym z nich uruchomiłem jeden wątek prędkość jest rzeczywiście dwa razy większa (porównując do pojedynczej instancji z jednym wątkiem). Średnie obciążenie procesora ~100%. I to jest ok, ale gdy:
Natomiast gdy uruchamiam jedną instancję programu, a w niej dwa wątki to nie uzyskuję żadnego przyspieszenia! Po prostu każdy wątek liczy dwa razy wolniej... Mimo to średnie obciążenie procesora ~93%
Oczywiście sprawdzałem czy wszystkie obliczenia dają poprawny wynik... Dla uproszczenia też każdy wątek (i niezależnie od tego ile ich jest) za każdym razem robi to samo...
A i wykorzystuję dość mocno pamięć podręczną - wykonuję dużo obliczeń na małej ilości danych. Większość z tych danych jest 'wspólna' dla obu wątków, aczkolwiek tylko z nich czytam, nic do nich nie zapisuję.
Właśnie sprawdziłem doświadczalnie - po powieleniu danych współdzielonych prędkość obliczeń wzrosła od razu. Czemu dane, które są dzielone między wątkami powodują aż tak duży narzut? Przecież ich nie modyfikuję i nie używam sekcji krytycznych, żeby się do nich odwołać... Jedyne co na nich robię to ich czytanie... Oczywiście dane te były inicjalizowane - ale tylko raz na samym początku działania programu.
Właśnie czytam poradnik http://www.agner.org/optimize/optimizing_cpp.pdf:
- The different threads need separate storage. No function or class that is used by
multiple threads should rely on static or global variables. The threads have each
their stack. This can cause cache contentions if the threads share the same cache.
Nie wiem czy dobrze to rozumiem - powinno być jak najmniej danych dzielonych między wątkami, nawet jeśli tylko je odczytuję (i dane te nie są też modyfikowane przez zewnętrzne procedury) i nie używam do tych celów żadnej synchronizacji?
A i mam procesor Core Duo :) Mam on jedną L2 dzieloną między oba rdzenie i każdy rdzeń ma też swój L1. Czy to jest tak, że jak jakaś dana jest w jednym L1, to nie może być w drugim? No bo co innego może powodować taki spadek wydajności?