Wielowątkowa paranoja

Jest to złożone pytanie, proszę dokładnie rozważyć przed udzieleniem odpowiedzi.

Zastanów się nad tą sytuacją. Dwa wątki (czytelnik i pisarz) uzyskują dostęp do jednego globalnego int. Czy to bezpieczne? Normalnie odpowiadałbym bez zastanowienia, tak! Wydaje mi się jednak, że Herb Sutter tak nie uważa. W swoich artykułach na temat efektywnej współbieżności omawia błędną kolejkę bez blokady i poprawioną wersję.

Na końcu pierwszego artykułu i na początku drugiego omawia rzadko rozważaną cechę zmiennych, kolejność zapisu. Int są atomowe, dobre, ale ints niekoniecznie są uporządkowane, które mogłyby zniszczyć dowolny algorytm bez blokady, w tym mój powyższy scenariusz. W pełni się Zgadzam, że jedynym sposobem na gwarancja poprawne zachowanie wielowątkowe na wszystkich platformach obecnych i przyszłych jest użycie atomiki (AKA bariery pamięci) lub muteksów.

Moje pytanie; czy write re-odering jest kiedykolwiek problemem na prawdziwym sprzęcie? Lub czy wielowątkowa paranoja jest po prostu pedantyczna?
A co z klasycznymi systemami uniprocesorowymi?
A co z prostszymi procesorami RISC, takimi jak wbudowany power-pc?

Wyjaśnienie: bardziej interesuje mnie to, co Pan Sutter powiedział o sprzęcie (procesor/cache) zmieniającym kolejność zapisu zmiennej. Mogę powstrzymać optymalizator przed łamaniem kodu za pomocą przełączników kompilatora lub ręcznej kontroli po kompilacji. Chciałbym jednak wiedzieć, czy sprzęt nadal może popsuć Kodeks w praktyce.

Author: deft_code, 2009-01-03

9 answers

Twój pomysł kontroli montażu nie jest wystarczająco dobry; Zmiana kolejności może nastąpić na poziomie sprzętu.

Aby odpowiedzieć na twoje pytanie "czy to jest kiedykolwiek problem na sprzęcie Odczytu:" Tak!W rzeczywistości sam napotkałem ten problem.

Czy można ominąć problem z systemami uniprocesorowymi lub innymi szczególnymi sytuacjami? Argumentowałbym "nie", bo za 5 lat będziesz musiał mimo wszystko działać na multi-core, a potem znalezienie tych wszystkich lokalizacji będzie trudne (niemożliwe?).

Jeden wyjątek: oprogramowanie przeznaczone dla wbudowanych aplikacji sprzętowych, w których rzeczywiście masz pełną kontrolę nad sprzętem. W rzeczywistości tak "oszukałem" w takich sytuacjach np. na procesorze ARM.

 26
Author: Jason Cohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 19:59:07

Yup-użyj barier pamięci, aby zapobiec zmianie kolejności instrukcji w razie potrzeby. W niektórych kompilatorach C++ słowo kluczowe volatile zostało rozszerzone, aby wstawić Ukryte bariery pamięci dla każdego odczytu i zapisu - ale nie jest to przenośne rozwiązanie. (Podobnie z połączonymi interfejsami API* win32). Vista dodaje nawet kilka nowych drobnoziarnistych interfejsów API, które pozwalają określić semantykę odczytu lub zapisu.

Niestety, C++ ma tak luźny model pamięci, że każdy taki kod będzie nie-przenośny do pewnego stopnia i będziesz musiał pisać różne wersje dla różnych platform.

 9
Author: Eclipse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 19:56:55

Jak powiedziałeś, z powodu zmiany kolejności na poziomie pamięci podręcznej lub procesora, faktycznie potrzebujesz jakiejś bariery pamięci, aby zapewnić właściwą synchronizację, szczególnie dla wielu procesorów (a zwłaszcza na platformach innych niż x86). (Dano mi wierzyć, że systemy jednoprocesorowe nie mają tych problemów, ale nie cytujcie mnie na ten temat- - - jestem zdecydowanie bardziej skłonny grać bezpiecznie i robić synchronizowany dostęp i tak.)

 5
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 19:51:13

Napotkaliśmy problem, choć na procesorach Itanium, gdzie Zmiana kolejności instrukcji jest bardziej agresywna niż x86/x64.

Poprawka polegała na użyciu instrukcji z blokadą, ponieważ nie było (w tym czasie) sposobu mówienia kompilatorowi, aby po prostu powiedział, ale bariera zapisu po przypisaniu.

Naprawdę potrzebujemy rozszerzenia języka, aby poradzić sobie z tym czysto. Użycie volatile (jeśli jest obsługiwane przez kompilator) jest zbyt gruboziarniste dla przypadków, w których próbujesz wycisnąć tyle wydajność z kawałka kodu, jak to możliwe.

 5
Author: Rob Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 20:16:50

Czy to kiedykolwiek problem na prawdziwym sprzęcie?

Absolutnie, szczególnie teraz, gdy przenosimy się na wiele rdzeni dla obecnych i przyszłych procesorów. Jeśli jesteś zależny od uporządkowanej atomiczności implementacji funkcji w swojej aplikacji i nie jesteś w stanie zagwarantować tego wymogu za pośrednictwem wybranej platformy lub korzystania z synchronizacji prymitywów, w warunkach wszystkie, tj. Przejście klienta z jednordzeniowego procesora do wielordzeniowego procesora, to po prostu czekasz na problem zaistnieć.

Cytowanie z cytowanego artykułu o herbie Sutter (drugi)

Uporządkowane zmienne atomowe są pisane na różne sposoby na popularnych platformach i środowiskach. Na przykład:

  • volatile W C#/. Net, jak w volatile int.
  • volatile lub * Atomic* w Javie, jak w volatile int, AtomicInteger.
  • atomic<T> W C++0x, nadchodzący Standard ISO C++, jak w atomic<int>.

Nie widziałem jak C++0x implementuje atomicity więc jestem nie można określić, czy nadchodząca funkcja językowa jest czystą implementacją biblioteki, czy też zależy również od zmian w języku. Możesz przejrzeć propozycję, aby sprawdzić, czy można ją włączyć jako niestandardowe rozszerzenie do obecnego łańcucha narzędzi, dopóki nowy standard nie będzie dostępny, może być nawet dostępny już dla twojej sytuacji.

 4
Author: Henk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 20:16:37

Jest to problem na prawdziwym sprzęcie. Mój przyjaciel pracuje dla IBM i zarabia na życie przede wszystkim poprzez wykrywanie tego rodzaju problemów w kodach klientów.

Jeśli chcesz zobaczyć, jak źle może być, poszukaj prac naukowych na temat modelu pamięci Java (a teraz również modelu pamięci C++). Biorąc pod uwagę zmianę kolejności, jaką może zrobić prawdziwy sprzęt, próba ustalenia, co jest bezpieczne w języku wysokiego poziomu, jest koszmarem.

 3
Author: Norman Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 20:08:40

Nie to nie jest bezpieczne i jest dostępny prawdziwy sprzęt, który wykazuje ten problem, na przykład model pamięci w chipie powerpc na Xboxie 360 pozwala na zmianę kolejności zapisu. Jest to pogłębione przez brak barier w wewnętrznych, zobacz ten artykuł na msdn aby uzyskać więcej szczegółów.

 2
Author: Rick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-17 05:03:05

Odpowiedź na pytanie "czy to bezpieczne" jest z natury niejednoznaczna.

Jest zawsze bezpieczny, nawet dla sobowtórów, w tym sensie, że Twój komputer nie zapali się. Jest to bezpieczne, w tym sensie, że zawsze otrzymasz wartość, którą int trzymał w pewnym momencie w przeszłości, To nie jest bezpieczne, w tym sensie, że możesz uzyskać wartość, która jest/będzie aktualizowana przez inny wątek.

"Atomic" oznacza, że otrzymujesz drugą gwarancję. Ponieważ double zwykle nie jest atomowy, możesz dostać 32 stare i 32 nowe bity. To niebezpieczne.

 1
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-05 09:55:04

Kiedy zadałem pytanie najbardziej interesował mnie uniprocesor powerpc. W jednym z Komentarzy InSciTek Jeff wspomniał o instrukcji powerpc SYNC i ISYNC. Tam, gdzie klucz do ostatecznej odpowiedzi. Znalazłem to Tutaj {[2] } na stronie IBM.

Artykuł jest duży i dość gęsty, ale zabranie jest nie, nie jest bezpieczne. W starszych PowerPC ' s optymalizatory pamięci, gdzie nie jest wystarczająco wyrafinowany, aby spowodować problemy na uniprocesor. Jednak nowsze są znacznie bardziej agresywny i może złamać nawet prosty dostęp do globalnego int.

 1
Author: deft_code,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:32:49