Dlaczego stan współdzielony obniża wydajność?


19

Pracowałem zgodnie z zasadą równoczesnego programowania bez udziału. Zasadniczo wszystkie moje wątki robocze mają niezmienne kopie tylko do odczytu tego samego stanu, które nigdy nie są udostępniane między nimi ( nawet przez odniesienie ). Ogólnie rzecz biorąc, działało to naprawdę dobrze.

Teraz ktoś wprowadził bufor singleton bez blokady ( np. Słownik statyczny ), do którego jednocześnie uzyskują dostęp wszystkie wątki. Ponieważ słownik nigdy nie jest zmieniany po uruchomieniu, nie ma blokad. Nie wystąpiły żadne problemy z bezpieczeństwem wątków, ale teraz nastąpił spadek wydajności.

Pytanie brzmi ... skoro nie ma żadnych blokad, dlaczego wprowadzenie tego singletonu tworzy hit? Co dokładnie dzieje się pod przykrywkami, które mogłyby to wyjaśnić?

Aby to potwierdzić, dostęp do tego nowego singletonu jest jedyną zmianą i mogę go wiarygodnie odtworzyć, po prostu komentując połączenie z pamięcią podręczną.


8
Czy wskazałeś profilera na kod?
Timo Geusch

2
Profilowanie raczej nie odpowie na to pytanie, chyba że profilujesz CLR i jądro systemu Windows (nie jest to łatwe zadanie dla przeciętnego programisty).
Igby Largeman,

1
@JoeGeeky Alrighty, myślę, że jedyne, co mogę dla mnie zrobić, to +1 i faworyzowanie! Wydaje się to dziwne, ponieważ obaj są w końcu na tym samym poziomie pośredni i mimo wszystko powinny zmieścić się w pamięci podręcznej procesora itp.
Max

2
FWIT Odrodziłem kilka wątków i uruchomiłem kilka timerów. Utworzyłem instancję klasy, singletonu, zablokowanego Singletona i dict <ciąg, ciąg>. Po pierwszym utworzeniu każdego z nich kolejne uruchomienia trwały około 2000ns dla każdego obiektu. Słownik działał 2x wolniej, może być spowodowany przez kod konstruktora ... jest wolniejszy niż sam blokada. Biorąc pod uwagę całą GC, obsługę OS kolejek wątków i inne koszty ogólne ... nie jestem pewien, czy naprawdę można odpowiedzieć na to pytanie. Jednak z moich wyników nie sądzę, że problem dotyczy singletonów. Nie, jeśli jest zaimplementowany jak w MSDN. Nie obejmuje optymalizacji kompilatora.
P.Brian.Mackey,

1
@JoeGeeky - inna myśl: czy użycie bufora zwiększa poziom pośredni? W przypadku częstego dostępu, ściganie dodatkowego derefa wskaźnika (lub odpowiednika MSIL) może wydłużyć czas w porównaniu z lokalną mniej pośrednią kopią.
sdg

Odpowiedzi:


8

Możliwe, że stan niezmienny dzieli linię bufora z czymś zmiennym. W takim przypadku zmiana pobliskiego stanu zmiennego może spowodować wymuszenie ponownej synchronizacji tej linii pamięci podręcznej na rdzeniach, co może spowolnić wydajność.


3
To brzmi jak false sharingscenariusz, który opisujesz. Aby to wyodrębnić, muszę profilować pamięć podręczną L2. Niestety, są to typy referencyjne, więc dodanie przestrzeni buforowej nie będzie możliwe, jeśli tak właśnie się dzieje.
JoeGeeky,

3

Upewniłbym się, że metody Equals()i GetHashCode()obiektów, których używasz jako kluczy do słownika, nie powodują żadnych nieoczekiwanych efektów ubocznych nieprzyjaznych wątkom. Profilowanie bardzo by tu pomogło.

Jeśli przez przypadek twoje klucze są ciągami, to być może masz je: plotka głosi, że ciągi zachowują się jak niezmienne obiekty, ale ze względu na pewne optymalizacje są one implementowane wewnętrznie w sposób zmienny, ze wszystkim, co wiąże się to z wielowątkowością .

Spróbowałbym przekazać słownik do wątków, które używają go jako zwykłego odniesienia zamiast singletonu, aby sprawdzić, czy problem leży w udostępnianiu, czy w singletonowości słownika. (Eliminacja możliwych przyczyn.)

Spróbowałbym również ConcurrentDictionaryzamiast zwykłego Dictionaryna wypadek, gdyby jego użycie przyniosło zaskakujące rezultaty. Jest wiele rzeczy do spekulacji na temat problemu, jeśli ConcurrentDictionaryokaże się, że działa znacznie lepiej lub znacznie gorzej niż zwykle Dictionary.

Jeśli żadne z powyższych nie wskazuje na problem, zgaduję, że obniżona wydajność jest spowodowana dziwnym sporem między wątkiem zbierającym śmieci a resztą twoich wątków, ponieważ śmieciarz próbuje dowiedzieć się, czy obiekty w twoim słowniku muszą zostać usunięte lub nie, podczas gdy są dostępne dla twoich wątków.

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.