Jak mogę napisać blokady wolnego strukturę?

głosy
35

W moim wielowątkowych aplikacji i widzę ciężką rywalizację blokady w nim, zapobiegając dobrą skalowalność w wielu rdzeni. Zdecydowałem się użyć blokady wolnego programowania, aby rozwiązać ten problem.

Jak mogę napisać blokady wolnego strukturę?

Utwórz 18/09/2008 o 12:18
źródło użytkownik
W innych językach...                            


21 odpowiedzi

głosy
5

Inmutability miałoby ten skutek. Zmiany przedmiotu doprowadzić do nowego obiektu. Lisp działa w ten sposób pod kołdrą.

Pozycja 13 z Effective Java wyjaśnia tę technikę.

Odpowiedział 18/09/2008 o 12:21
źródło użytkownik

głosy
0

Cóż, to zależy od rodzaju konstrukcji, ale trzeba zrobić strukturę tak, aby dokładnie i cicho wykrywa i obsługuje ewentualnych konfliktów.

Wątpię, można zrobić jeden, który jest w 100% wolne od zamka, ale znowu, to zależy od tego, jakiego rodzaju struktury trzeba zbudować.

Można również trzeba shard strukturę tak, że wiele wątków pracy na poszczególne pozycje, a potem na zsynchronizować / rekombinacji.

Odpowiedział 18/09/2008 o 12:22
źródło użytkownik

głosy
12

Pisanie blokady wątek bezpieczny bezpłatny kod jest trudne; ale ten artykuł z Herb Sutter będzie Ci zacząć.

Odpowiedział 18/09/2008 o 12:23
źródło użytkownik

głosy
0

Jak wspomniano, to naprawdę zależy od tego, jakiego rodzaju struktury mówisz. Na przykład, można napisać ograniczoną kolejkę blokady wolne, ale nie taki, który umożliwia swobodny dostęp.

Odpowiedział 18/09/2008 o 12:24
źródło użytkownik

głosy
7

Niezmienność jest jedno podejście, aby uniknąć blokowania. Zobacz dyskusję Eric Lippert za i wdrażanie takich rzeczy niezmiennych stosów i kolejek.

Odpowiedział 18/09/2008 o 12:24
źródło użytkownik

głosy
15

Korzystać z biblioteki, takich jak Intel Threading Building Blocks , zawiera sporo struktur blokada -Darmowy i algorytmy. I naprawdę nie polecam próby zapisu blokady bezpłatny kod siebie, jest niezwykle podatny na błędy i trudno uzyskać prawo.

Odpowiedział 18/09/2008 o 12:25
źródło użytkownik

głosy
0

Zmniejszyć lub wyeliminować wspólny stan zmienny.

Odpowiedział 18/09/2008 o 12:26
źródło użytkownik

głosy
1

Podstawową zasadą dla synchronizacji blokady wolna jest taka:

  • kiedy czytasz strukturę, należy wykonać odczyt z testem, czy struktura została zmutowana odkąd zaczął czytać, a ponownie, dopóki nie uda się bez czytania coś innego idzie i mutowania jednocześnie robisz tak;

  • gdy jesteś mutacji strukturę, zorganizować swój algorytm i dane tak, że jest tylko jeden krok atomowej, która, jeśli wzięte powoduje, że cała zmiana stają się widoczne dla innych wątków i zorganizować wszystko tak, że żadna zmiana jest widoczna chyba że krok jest podjęta. Użyć cokolwiek lockfree mechanizm atomowa istnieje na platformie dla tego etapu (np porównać-i-set, obciążenia związane + magazyn warunkowe, etc.). W tym kroku należy następnie sprawdzić, czy jakakolwiek inna Wątek zmutowane obiekt ponieważ operacja mutacja zaczęła popełniać jeśli nie ma i zacząć od nowa, jeśli ma.

Istnieje wiele przykładów blokady wolne struktur w sieci; nie wiedząc o tym, co masz wykonawczych i na jakiej platformie trudno być bardziej szczegółowe.

Odpowiedział 18/09/2008 o 12:28
źródło użytkownik

głosy
1

Większość algorytmów lub struktur lock-wolny początek jakiejś operacji atomowych, czyli zmiany w jakimś miejscu w pamięci, że po rozpoczętej przez wątek zostanie zakończony zanim jakikolwiek inny wątek może wykonać tę samą operację. Czy masz takiej operacji w swoim otoczeniu?

Patrz tutaj dla kanonicznej papieru na ten temat.

Również spróbować tej Artykuł Wikipedii artykuł na dalsze pomysły i linki.

Odpowiedział 18/09/2008 o 12:32
źródło użytkownik

głosy
42

Odpowiedź jest krótka:

Nie możesz.

Długa odpowiedź brzmi:

Jeśli zadajesz to pytanie, nie wiem, chyba na tyle, aby móc stworzyć blokady wolnego strukturę. Tworzenie Lock Free struktury jest niezwykle trudne, a tylko eksperci w tej dziedzinie może to zrobić. Zamiast pisać własną rękę, szukać istniejącej implementacji. Kiedy go znaleźć, sprawdzić, jak to jest powszechnie stosowane, jak dobrze jest udokumentowane, jeśli jest dobrze udowodnione, jakie są ograniczenia - nawet niektóre zablokować swobodny struktura inni publikowane są podzielone.

Jeśli nie znaleźć wolnego blokady strukturę odpowiadającą strukturze aktualnie używanego raczej dostosowanie algorytmu, dzięki czemu można korzystać z niektórych istniejący.

Jeśli nadal nalegać na tworzenie własnej struktury wolnego blokady, należy:

  • zacząć od czegoś bardzo prostego
  • zrozumieć modelu pamięci platformy docelowej (w tym odczytu / zapisu zamianom ograniczeń, jakie operacje są atomowy)
  • uczyć się wiele o problemach innych ludzi napotkanych podczas wdrażania Lock Free struktur
  • Nie tylko, że jeśli to będzie działać, to udowodnić
  • ciężko przetestować rezultat

Więcej przeczytać:

Zablokować wolne i czekają bezpłatne algorytmów w Wikipedii

Herb Sutter: Blokada-Free Kod: fałszywe poczucie bezpieczeństwa

Odpowiedział 18/09/2008 o 12:36
źródło użytkownik

głosy
4

Cliff Kliknij posiada kopułę niektórych głównych badania na blokowaniu wolnych struktur danych przy wykorzystaniu automat skończony, a także pisał wiele implementacji Java. Można znaleźć swoje dokumenty, slajdy i implementacje na swoim blogu: http://blogs.azulsystems.com/cliff/

Odpowiedział 18/09/2008 o 12:37
źródło użytkownik

głosy
12

Jak sblundy wskazał, czy wszystkie obiekty są niezmienne, tylko do odczytu, nie trzeba się martwić o blokowania, jednak oznacza to, być może trzeba będzie skopiować obiekty dużo. Kopiowanie zwykle wiąże malloc i malloc korzysta blokowania zsynchronizować alokacji pamięci przez wątków, więc niezmienne obiekty mogą kupić ci mniej niż myślisz (sama malloc Wagi raczej źle i malloc jest powolny , jeśli dużo malloc zrobić w krytycznym punkcie wydajności Don „t spodziewać się dobrych wyników).

Kiedy trzeba tylko zaktualizować zmienne proste (np 32 czy 64 bit int lub wskaźniki), należy wykonać po prostu dodawanie lub odejmowanie operacji na nich lub po prostu zamienić wartości dwóch zmiennych, większość platform oferują „Operacje atomowe” tego (dalej GCC oferuje te także). Atomic nie jest taka sama jak bezpieczny wątku . Jednak atomowa sprawia pewien, że jeśli jeden wątek zapisuje wartość 64 bitową do miejsca pamięci dla przykładu i inny wątek czyta z niej odczyt jednego albo pobiera wartość przed operacją zapisu lub po operacji zapisu, ale nigdy złamany wartość w międzyczasie operacji zapisu (np jedno gdzie pierwsze 32 bity są już nowe, ostatnie 32 bit są nadal stara wartość! To może się zdarzyć, jeśli nie korzystają z dostępu atomową na takiej zmiennej).

Jednakże, jeśli masz struct C z 3 wartości, które chcesz zaktualizować, nawet jeśli aktualizować wszystkie trzy z operacji atomowych, są to trzy niezależne operacje, więc czytelnik może zobaczyć struct z jedną wartość już jest aktualizacja i dwa nie będąc aktualizowana. Tutaj trzeba będzie blokady, jeśli trzeba zapewnić, czytelnik albo widzi wszystkie wartości w struktury będącej albo stare lub nowe wartości.

Jednym ze sposobów, aby zamki skalować wiele lepiej jest przy użyciu R / W zamki. W wielu przypadkach, aktualizacje danych są raczej rzadkie (operacje zapisu), ale dostęp do danych jest bardzo częste (odczyt danych), pomyśl o kolekcjach (hashtables, drzewa). W tym przypadku R / W zamki kupi ci ogromny wzrost wydajności, jak wiele wątków może pomieścić do odczytu-lock w tym samym czasie (nie będą blokować siebie) i tylko wtedy, gdy jeden wątek chce blokady zapisu, wszystkie inne wątki są blokowane na czas aktualizacji jest wykonywana.

Najlepszym sposobem na uniknięcie problemów jest nitki nie udostępnia żadnych danych w wątkach. Jeśli każdy wątek zajmuje większość czasu z danymi żaden inny wątek ma dostęp do, nie trzeba do tego blokowania danych na wszystkich (także żadne operacje atomowe). Więc staramy się udostępniać jak mało danych, jak to możliwe między wątkami. Następnie trzeba szybki sposób przenoszenia danych pomiędzy wątkami tylko jeśli naprawdę trzeba (ITC, Inter Communication gwintem). W zależności od systemu operacyjnego, platformy i języka programowania (niestety powiedziano nam, żadna z tych), mogą istnieć różne potężne sposoby ITC.

I wreszcie kolejna sztuczka do pracy z udostępnionych danych, ale bez blokowania jest upewnienie się wątki nie korzysta z tych samych częściach wspólnych danych. Np jeśli dwa wątki podziel tablicę, ale tylko jeden kiedykolwiek dostęp, nawet, drugi tylko indeksy nieparzyste, trzeba żadnej blokady. Albo wtedy, gdy oba dzielić ten sam blok pamięci i jeden używa tylko górną połowę, drugi tylko dolna, trzeba żadnej blokady. Choć nie jest powiedziane, że doprowadzi to do dobrych wyników; szczególnie nie na wielordzeniowych procesorach. Operacji zapisu jednego wątku do tej udostępnionych danych (uruchomiony jeden rdzeń) może zmusić cache należy przepłukać na innym wątku (działającego na innym rdzeniu) i te opróżnia cache są często wąskim gardłem dla wielowątkowych aplikacji uruchamianych na nowoczesnych wielordzeniowych procesorów.

Odpowiedział 18/09/2008 o 12:42
źródło użytkownik

głosy
0

W Javie wykorzystują pakiety java.util.concurrent w JDK 5+ zamiast pisać własne. Jak wspomniano powyżej, to jest naprawdę pole dla ekspertów, a jeśli nie masz zapasowy rok lub dwa, toczenia własne nie jest rozwiązaniem.

Odpowiedział 18/09/2008 o 13:42
źródło użytkownik

głosy
1

Jeśli piszesz własnych struktur danych lock-wolny dla wielordzeniowych procesorów, nie zapomnij o bariera pamięci! Należy także rozważyć patrząc w pamięci Software transakcja technik.

Odpowiedział 18/09/2008 o 14:24
źródło użytkownik

głosy
2

Użyj istniejącego wdrożenia, jak ten obszar pracy jest sfera ekspertów w tej dziedzinie i doktorów (jeśli chcesz to zrobić dobrze!)

Na przykład nie jest biblioteką kod tutaj:

http://www.cl.cam.ac.uk/research/srg/netos/lock-free/

Odpowiedział 18/09/2008 o 14:30
źródło użytkownik

głosy
0

Można wyjaśnić, co masz na myśli przez struktury?

Teraz, jestem przy założeniu, masz na myśli ogólną architekturę. Można to osiągnąć przez nie wspólnej pamięci między procesami, a przy użyciu modelu aktor procesów.

Odpowiedział 18/09/2008 o 15:06
źródło użytkownik

głosy
0

Spójrz na mojego łącza ConcurrentLinkedHashMap na przykład, jak napisać strukturę danych lock-free. To nie jest oparta na żadnych prac naukowych i nie wymaga lat badań, jak inni sugerują. To po prostu trwa starannej inżynierii.

Moja implementacja nie używać ConcurrentHashMap, który jest algorytm lock-per-wiadrze, ale to nie zależy od tego szczegółach implementacji. To może być łatwo zastąpiony realizacji blokady wolne Cliffa Kliknij na. Pożyczyłem pomysł z Cliff, ale używane znacznie bardziej wyraźnie, jest modelowanie wszystkich operacji CAS maszynie państwowej. To znacznie upraszcza model, a zobaczysz, że mam zamki pseudohalogenek via „państwami ING. Inną sztuczką jest umożliwienie lenistwo i rozwiązywać w miarę potrzeb. Zobaczysz to często z wycofywania lub pozwalając innych wątków „pomocy” do czyszczenia. W moim przypadku, postanowiliśmy umożliwić martwe węzły na liście być eksmitowany, gdy dotrą one do głowy, zamiast kontrakt ze złożonością usuwając je ze środka listy. może to zmienić, ale nie całkowicie zaufać mój algorytm Backtracking i chciał odkładać poważnej zmiany jak przyjęcie podejścia blokujący 3-węzła.

Książka „The Art of Wieloprocesorowy Programming” jest doskonałym starter. Generalnie jednak, polecam unikanie blokad wolne projekty w kodzie aplikacji. Często jest to po prostu przesada gdzie inne, mniej podatne na błędy, techniki są bardziej odpowiednie.

Odpowiedział 20/09/2008 o 01:26
źródło użytkownik

głosy
6

w re. Odpowiedź Sumy, Maurice Herlithy pokazuje w sztuce programowania Wieloprocesorowy faktycznie cokolwiek może być napisany bez blokad (patrz rozdział 6). iirc, ta w istocie polega na elementy rozdzielających zadania węzła obróbki (takiej jak funkcja zamknięcia), a enqueuing każdy. Nici obliczy stan wykonując wszystkie węzły z najnowszej pamięci podręcznej jeden. Oczywiście to może w najgorszym przypadku doprowadzić do sekwencyjnego wykonania, ale ma ważne właściwości lockless, zapobiegając scenariuszy, w których nici mogła dostać się do zaplanowanych długich peroids czasu, kiedy trzymają zamki. Herlithy osiąga również teoretyczną wydajność wait-wolny, co oznacza, że jeden wątek nie skończy się na zawsze czeka do wygrania Kolejkuj Atomowej (to jest dużo skomplikowanego kodu).

Wielowątkowy kolejka / stos jest zaskakująco twarde (sprawdzenia problemu ABA ). Inne rzeczy może być bardzo proste. Przyzwyczaić się do while (true) {atomicCAS aż zamieniłem it} bloków; są niezwykle silne. Intuicja za to, co jest poprawne z CAS może pomóc w rozwoju, choć należy użyć dobrego testowania i być może bardziej zaawansowane narzędzia (może szkic , zbliżający MIT Kendo lub typu spin ?) W celu sprawdzenia poprawności, czy można je zmniejszyć do prostej konstrukcji.

Proszę pisać więcej o swoim problemie. Trudno dać dobrą odpowiedź bez szczegółów.

edit immutibility jest ładny, ale to przydatność jest ograniczona, jeśli mam zrozumienia go w prawo. To naprawdę nie ma przezwyciężyć zapisu po odczycie zagrożeń; rozważyć dwa wątki realizującego "MEM = NEWNODE (MEM)"; mogli zarówno czytać mem, a następnie zarówno pisać; nie poprawna dla klasycznych funkcji przyrostu. Ponadto, jest to prawdopodobnie ze względu na powolny alokacji sterty (który ma być synchronizowany całej wątków).

Odpowiedział 09/04/2009 o 06:50
źródło użytkownik

głosy
1

Jeśli widzisz blokady twierdzenie, chciałbym najpierw spróbować użyć bardziej szczegółowe zamki na swoich struktur danych zamiast algorytmów całkowicie lock-free.

Na przykład, obecnie pracuje wielowątkowych zastosowania, który posiada system niestandardowych wiadomości (lista kolejek dla każdej nici, kolejka zawiera wiadomości dla nici do procesu) do przekazywania informacji między gwintami. Jest to globalna blokada na tej strukturze. W moim przypadku nie ma potrzeby prędkość tak dużo, więc to naprawdę nie ma znaczenia. Ale jeśli ta blokada by stać się problemem, może być zastąpiony przez poszczególnych zamków w każdej kolejce, na przykład. Następnie dodawania / usuwania elementu do / od konkretnej kolejce nie miało wpływu innych kolejek. Nadal będzie globalna blokada dodając nową kolejkę i takie, ale to nie będzie tak bardzo podniosła.

Nawet pojedynczy wielo-produkuje kolejka / konsument może być napisany z blokadą ziarnistej na każdym elemencie, zamiast globalnej blokady. Może to również wyeliminować rywalizację.

Odpowiedział 09/04/2009 o 07:02
źródło użytkownik

głosy
9

Jako mojego profesora (NIR Shavit z "The Art of Programming") Wieloprocesorowy powiedział klasę: Proszę nie robić. Głównym powodem jest testowalność - nie można przetestować kod synchronizacji. Można uruchomić symulacje, można nawet stres test. Ale to w najlepszym przybliżeniem. Co naprawdę potrzebne jest matematyczny dowód poprawności. I bardzo mało zdolny zrozumienie ich, niech sam je pisze. Tak, jak inni powiedział: wykorzystanie istniejących bibliotek. Blogi Joe Duffy ankiet niektóre techniki (rozdział 28). Pierwszy z nich należy spróbować drzewo jest dzielenie - przerwa na mniejsze zadania i łączyć.

Odpowiedział 09/04/2009 o 07:47
źródło użytkownik

głosy
0

Jeśli czytasz kilka implementacje i dokumenty dotyczące przedmiotu, można zauważyć, że jest następujący wspólny motyw:

1) Udostępnione obiekty państwowe są LISP / clojure styl inmutable : czyli wszystkie operacje zapisu są realizowane kopiując istniejący stan w nowym obiekcie, dokonać modyfikacji do nowego obiektu, a następnie spróbuj zaktualizować wspólny stan (otrzymaną z wyrównanym wskaźnikiem, że może być aktualizowana z CAS prymitywnego). Innymi słowy, nawet nigdy nie zmodyfikować istniejący obiekt, który może być odczytany przez ponad bieżącego wątku. Inmutability mogą być optymalizowane przy użyciu kopiowanie przy zapisie semantykę dla dużych, skomplikowanych obiektów, ale to kolejny drzewa orzechów

2) wyraźnie określić, co pozwoliło przejścia między bieżącym i przyszłym stanie są ważne : Wtedy walidacji, że algorytm jest poprawny stać rzędów wielkości łatwiejsze

3) uchwytu odrzucone odniesienia na listach wskaźnik zagrożenia na wątek . Po obiekty referencyjne są bezpieczne, ponownego użycia, jeśli to możliwe

Zobacz innym pokrewnym stanowisku kopalni, gdzie niektóre kod realizowane z semaforów i muteksy jest (częściowo) przepisany w stylu blokady bezpłatny: Wzajemne wykluczanie i semaforów

Odpowiedział 11/11/2010 o 17:38
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more