W trakcie próby zrozumienia, jak radzić sobie z kodem bez blokady, próbowałem napisać pojedynczą blokadę wolnego klienta/pojedynczego producenta. Jak zwykle sprawdzałem artykuły, artykuły i kod, szczególnie biorąc pod uwagę, że jest to dość delikatny temat.Używanie std :: memory_order_consume w kolejce SPV w kolejce wolnych SPL
Tak, natknąłem się na wdrożenie tej struktury danych w bibliotece Folly, które można znaleźć tutaj: https://github.com/facebook/folly/blob/master/folly/ProducerConsumerQueue.h
As każdego zamka wolne kolejce widziałem, ten wydaje się używać buforze cyklicznym, więc mamy dwie zmienne std::atomic<unsigned int>
: readIndex_
i writeIndex_
. readIndex_
wskazuje następny indeks, przy którym będziemy czytać, i writeIndex_
następny, przy którym będziemy pisać. Wydaje się dość proste.
Tak więc wdrożenie wydaje się być czyste i dość proste od pierwszego wejrzenia, ale znalazłem jedną rzecz kłopotliwą. Rzeczywiście, niektóre funkcje, takie jak isEmpty()
, isFull()
lub guessSize()
, używają std::memory_order_consume
do pobierania wartości indeksów.
I szczerze mówiąc, naprawdę nie wiem, w jakim celu służą. Nie zrozumcie mnie źle, zdaję sobie sprawę z zastosowania std::memory_order_consume
w klasycznym przypadku przenoszenia zależności przez wskaźnik atomowy, ale tutaj wydaje się, że nie mamy żadnej zależności! Właśnie dostaliśmy indeksy, liczby całkowite bez znaku, nie tworzymy zależności. Dla mnie w tym scenariuszu std::memory_order_relaxed
jest równoważny.
Jednak nie ufam sobie, że lepiej rozumiem pamięć zamawianą niż ci, którzy opracowali ten kod, dlatego dlatego zadaję to pytanie tutaj. Czy jest coś, co przegapiłem lub źle zrozumiałem?
Z góry dziękuję za odpowiedzi!
Niewiele jest przypadków, w których 'std :: memory_order_relaxed' faktycznie będzie miało jakąkolwiek różnicę.Naprawdę potrzebujesz mikroukładu zdolnego do rozdarcia odczytu/zapisu. Przykładem jest x86, gdy mamy do czynienia z danymi niewyrównanymi, ale ty nie. Powodem, dla którego mówię to wszystko jest to, że jeśli myślisz, że coś wymaga 'memory_order_relaxed', prawdopodobnie nie rozumiesz użycia. Czy próbujesz zapobiec rozdarciu odczytu/zapisu? – SergeyA
@SideEffects: Zgadzam się z tobą. Nie ma późniejszych dostępów do pamięci, które zależą od wartości indeksu w tych funkcjach, więc nie rozumiem, w jaki sposób 'std :: memory_order_consume' mógłby wnieść coś użytecznego. Autor (s) Adresy e-mail są na górze pliku; może spróbuj wysłać je e-mailem? (Jeśli to zrobisz, dodaj tutaj aktualizację lub odpowiedź.) Ciekaw jestem, czy czegoś brakuje.) – Nemo
@SergeyA Tak, być może było to trochę niejasne. Chciałem tylko powiedzieć, że uważałem, że porządkowanie pamięci konsumpcyjnej było, przynajmniej dla mnie, nie dodawaniem niczego użytecznego. Ale ja, może chcę wyjaśnić ten punkt, dzięki! – SideEffects