2011-07-01 14 views
11

Jeśli pojedyncza 32-bitowa zmienna jest współdzielona między wieloma wątkami, czy powinienem umieścić blokadę mutex wokół zmiennej? Załóżmy na przykład, że 1 wątek zapisuje do 32-bitowego licznika, a drugi wątek go odczytuje. Czy jest jakaś szansa, że ​​drugi wątek mógł odczytać uszkodzoną wartość?Czy powinienem mutex zablokować pojedynczą zmienną?

Pracuję nad 32-bitowym systemem wbudowanym ARM. Kompilator zawsze wydaje się dopasowywać 32-bitowe zmienne, aby można je było odczytać lub zapisać za pomocą pojedynczej instrukcji. Jeśli 32-bitowa zmienna nie była wyrównana, to odczyt lub zapis byłby podzielony na wiele instrukcji, a drugi wątek mógłby odczytać uszkodzoną wartość.

Czy odpowiedź na to pytanie ulegnie zmianie, jeśli przejdę do systemu wielordzeniowego w przyszłości, a zmienna jest dzielona między rdzeniami? (zakładając wspólną pamięć podręczną między rdzeniami)

Dzięki!

+3

Dbasz o wyścigi, czy martwisz się tylko łzawieniem? –

+2

Gdy już się upewnisz, że nie ma łez, pamiętaj, aby nie pisać "i ++" lub "i + = j" bez muteksu. –

+1

Dzięki za komentarz na temat łzawienia - nie wiedziałem, że tak się nazywało. Zastanawiam się głównie, co jest "standardem" i/lub czym jest "dobra praktyka", aby uniknąć zarówno łzawienia, jak i warunków wyścigu. – Will

Odpowiedz

8

Mutex chroni Cię przed czymś więcej niż tylko łzawieniem - na przykład niektóre implementacje ARM używają wykonywania poza kolejnością, a muteks będzie zawierał bariery pamięci (i kompilatora), które mogą być niezbędne dla poprawności twojego algorytmu.

Bezpieczniej jest dołączyć muteks, a następnie wymyślić sposób jego optymalizacji, jeśli okaże się, że jest to problem z wydajnością.

Należy również zauważyć, że jeśli twój kompilator jest oparty na GCC, możesz mieć dostęp do GCC atomic builtins.

+0

Dzięki za wszystkie szczegóły. Czytanie http://www.usenix.org/event/hotpar11/tech/final_files/Boehm.pdf przekonało mnie, że masz rację. – Will

3

Nie potrzebujesz muteksu. W 32-bitowym ARM pojedynczy zapis lub odczyt jest operacją atomową. (niezależnie od liczby rdzeni) Oczywiście należy zadeklarować tę zmienną jako zmienną.

+1

Dla mojego prostego przypadku powyżej, myślę, że to ma sens. Jednak komentarz Davida Heffernana na temat łez doprowadził mnie do http://www.usenix.org/event/hotpar11/tech/final_files/Boehm.pdf. Ta praca sprawia, że ​​jestem bardziej nerwowy w związku z łagodnymi wyścigami danych i jak "lotny" może nie być kompletnym rozwiązaniem. – Will

4

Jeśli cały zapis jest wykonywany z jednego wątku (to znaczy, że inne wątki są tylko odczytywane), to znaczy, że nie potrzebujesz muteksu. Jeśli pisze więcej niż jeden wątek, robisz to.

1

W systemie 32-bitowym odczyty i zapisy 32-bitowych zmiennych są atomowe. Jednak zależy to od tego, co jeszcze robisz ze zmienną. Na przykład. jeśli jakoś to zmanipulujesz (np. dodasz wartość), to wymaga odczytu, manipulacji i zapisu. Jeśli procesor i kompilator nie obsługują w tym celu operacji atomowej, musisz użyć muteksa, aby chronić tę sekwencję wielozadaniową.

Istnieją inne techniki bez blokady, które mogą zmniejszyć zapotrzebowanie na muteksy.

+0

czy cpus z nieatomową operacją "przenoszenia" istnieje? Wierzyłem, że każda instrukcja komputera, która aktualizuje wartość lokalizacji pamięci, ma charakter atomowy i wszystko, o co należy zadbać, to fakt, że jeden wątek może odczytywać starą wartość zamiast zaktualizowanej (w przypadku pisania jednego wątku, a tylko drugi). czytanie oczywiście) – ShinTakezou

+0

@ShinTakezou - ARM wygeneruje nieatomowy odczyt/zapis, jeśli zmienna 32-bitowa nie jest wyrównana. (to znaczy., spowoduje ładowanie 4-bajtowe zamiast słowa load, aby uniknąć niezaalecanego wyjątku dostępu). – Will

+0

ARM lub kompilator? Przypuszczam, że to od kompilatora zależy generowanie poprawnego kodu; a ponieważ kompilator "wie", to faktycznie generuje 4 instrukcje zamiast jednej dla pojedynczego zapisu, może umieścić "bariery" w celu uczynienia całego zapisu atomowym i aby uniknąć programisty C, aby martwić się o szczegóły sprzętu źródło jest skompilowane dla (być może musi być opcja wyłączenia tych barier, ale dla mnie powinny one być dodane domyślnie, jeśli jest to oczywiście możliwe, i przypuszczam, że powinno być) – ShinTakezou