Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Czy są jakieś konkretne przypadki użycia, w których muteksy są znacznie szybsze niż kanały


Czy są jakieś konkretne przypadki użycia, w których muteksy są znacznie szybsze niż kanały


Mutexy mogą być znacznie szybsze niż kanały w określonych przypadkach użycia przede wszystkim ze względu na ich lekki charakter i sposób zarządzania rywalizacji i synchronizacji. Oto szczegółowe wyjaśnienia z kontekstami, w których muteksy przewyższają kanały:

Podstawowe różnice wpływające na wydajność

Mutexes zapewniają wzajemne wykluczenie, umożliwiając tylko jeden wątek lub goroutinę dostęp do sekcji krytycznej na raz. Wewnętrznie operacja Mutex zwykle obejmuje instrukcje atomowe i może obejmować blokowanie poziomu jądra tylko wtedy, gdy istnieje rywalizacja. Z tego powodu niekwestionowane operacje Mutex Lock/odblokowanie często kosztują tylko kilka nanosekund.

Natomiast kanały to abstrakcje na wyższym poziomie zaprojektowane do komunikacji między gorutinami lub wątkami. Wysyłanie lub odbieranie kanału obejmuje zarządzanie kolejką, możliwe przydziały pamięci, planowanie Goroutines i budzenie ich w przypadku snu. Ten koszt ogólny oznacza nawet proste mutacje stanowe strzeżone przez kanał ponoszą więcej kosztów w porównaniu z muxem ze względu na przełączanie kontekstu i prace koordynacyjne.

Te fundamentalne różnice już wskazują, dlaczego w przypadku prostej wspólnej ochrony zmiennej lub sekcji krytycznych muteksy są na ogół szybsze.

przypadki użycia, w których mutexy są szybsze

Simple udostępniona ochrona stanu

Gdy program musi chronić wspólne zmienne - takie jak liczniki, mapy lub proste flagi, są znacznie szybsze, ponieważ sekcja krytyczna obejmuje minimalny koszt synchronizacji. Przykłady obejmują:

- Liczenie żądań na serwerze WWW: Każda operacja przyrostu żądania może być pilnowana przez Mutex, nie wymagając kosztów wysyłania wiadomości przez kanał, co dodaje opóźnienia w kolejce i planowaniu. Mutexy umożliwiają prosty, bezpośredni dostęp i wykazano, że poprawia przepustowość o rząd wielkości lub więcej.

- Dostęp do wspólnych pamięci podręcznych lub map: ochrona struktur danych za pomocą Mutexes oferuje odczyty i zapisy w linii z minimalnym kosztami ogólnymi. Korzystanie z kanałów jako pośredników tutaj wprowadza dodatkowe opóźnienie, ponieważ każdy dostęp staje się żądaniem odpowiedzi w obie strony.

Testy porównawcze pokazują, że liczniki oparte na Mutex mogą być około 75 razy szybsze niż liczniki oparte na kanałach ze względu na zmniejszone koszty synchronizacji i unikanie kosztów zarządzania kolejką i przełączaniem kontekstu związanego z kanałami.

Niskie rywalizację lub niezakończone scenariusze

W środowiskach o niskich rywalizacjach Mutex Lock i odblokowanie operacji to prawie tylko operacje atomowe bez czasu oczekiwania. W przypadku niezakończonego przypadku błyszczącego mutexy, ponieważ blokowanie jest lekkie i zwykle nie wyzwala harmonogramu poziomu jądra.

Kanały ponoszą jednak koszty nawet w niskiej rywalizacji, ponieważ każde wysyłanie/odbieranie wymaga bardziej złożonego zarządzania, buforowania i synchronizacji. Zatem w przypadku niewielkiej liczby goroutinów lub w scenariuszach z niewielkim sporem, Mutexes znacznie przewyższają kanały.

Wysoka współbieżność z prostym blokowaniem

W scenariuszach, w których wiele Goroutyn wykonuje bardzo krótkie krytyczne sekcje, które modyfikują wspólny stan, Mutekse nadal są bardziej wydajne niż kanały. Kluczowym powodem jest to, że Mutexes Block walczy z Goroutinami w jądrze, umożliwiając wydajne harmonogram i budzenie dokładnie jednej goroutiny podczas odblokowywania. Z drugiej strony kanały obejmują aktywne harmonogramowanie Goroutine i zarządzanie kolejką, które wytwarza obciążenie obciążenia.

Na przykład, wskaźniki, w których zaangażowane są do 10 Goroutinów, pokazują, że muteksy są wielokrotnie szybsze, a muteksy pozostają konkurencyjne, nawet przy setkach gorutin.

Dystrybucja pracy, gdy mutacje stanowe są minimalne

Do zarządzania plasterkami lub listami zadań muteksy mogą być szybsze podczas krótkiego blokowania zadań. Chociaż kanały są bardzo naturalne w zakresie dystrybucji zadań, jeśli sekcja krytyczna jest krótka, a stan wspólny wymaga szybkiego blokowania i odblokowania, muteksy unikają dodatkowego kosztu koordynacji kanału i zapewniają lepszą przepustowość.

W wielu rzeczywistych systemach, takich jak pule pracowników lub kolejki pracy, mutexy mogą być prostsze i szybsze do zarządzania listami zadań w porównaniu z kanałami.

Dlaczego mutexy są szybsze w tych przypadkach

- Niższe koszty ogólne: Mutexes używają instrukcji procesora atomowego bezpośrednio do blokowania i odblokowywania, często bez przełącznika kontekstowego lub kosztownych decyzji dotyczących planowania.

- Blokowanie jądra z kolejkowaniem: rywalizowanie Goroutins śpią na muxes, tworząc kolejkę, a harmonogram budzi je seryjnie. Kanały powodują bardziej złożone wzorce budzenia i planowania.

- Brak kosztów przekazywania wiadomości: Kanały muszą przydzielić bufory lub wpisy kolejki oraz dane kopiowania/przesyłania, co nie jest konieczne, gdy wystarczy prosta własność i wyłączność.

- Dostęp do pamięci bezpośrednie: Mutexes umożliwiają bezpośredni dostęp do pamięci w sekcji krytycznej, podczas gdy kanały wymagają wysyłania danych za pośrednictwem medium komunikacyjnego, dodawania warstw pośredniego i opóźnienia.

konteksty mniej odpowiednie dla kanałów

Chociaż kanały stanowią elegancki i bezpieczny sposób komunikowania się między Goroutinami i są bardzo cenne do przetwarzania rurociągów i obsługi zdarzeń, ich koszty ogólne czyni je mniej odpowiednimi do krótkich, częstych mutacji państwowych.

Kanały są idealne, gdy synchronizacja złożonych obliczeń obejmujących wiele gorutin, w których semantyka przekazywania wiadomości jest naturalna i korzystna. Ale dla prostego blokowania błyszczą Mutexes.

Dowody eksperymentalne i porównawcze

- Benchmarki z synchronizacją Go GO pokazują, że liczniki Mutex działają z opóźnieniami w zakresie nanosekund, podczas gdy liczniki kanałów są rzędami wielkości wolniej (np. 0,8 ns vs. 60 ns na operację).

- Wydajność odwraca tylko w bardzo wysokich skalach (np. Tysiące gorutin), gdy kanały mogą przewyższyć muteksy w niektórych przypadkach, ponieważ kanały unikają blokowania kosztów ogólnych i lepszych modeli równoczesnych rurociągów.

- Zgodnie z rywalizacjami przewyższają spinloki z powodu wydajności planowania na poziomie jądra.

- Mutexy unikają alokacji pamięci i przełączania kontekstu obecnych w kanałach, co prowadzi do znacznych zysków w zakresie przepustowości i niższego wykorzystania procesora w celu ochrony wspólnych zmiennych.

Podsumowanie zaleceń dotyczących przypadków użycia

- Użyj muteksów podczas ochrony współdzielonej pamięci lub zmiennego stanu dostępu jednocześnie, zwłaszcza jeśli sekcja krytyczna jest krótka i obejmuje proste operacje.

- Użyj kanałów do organizowania obliczeń, rurociągów i architektur opartych na zdarzeniach, w których komunikaty reprezentują stan lub zadania, które mają być przetwarzane asynchronicznie.

- W przypadku kodu krytycznych w zakresie wydajności obejmującego mutacje stanu bezpośrednie przez wiele wątków lub goroutyny, mutexy zwykle zapewniają lepszą przepustowość i niższe opóźnienie.

- Rozważ kanały, gdy logika współbieżności korzysta z semantyki przekazywania wiadomości, ale unikaj ich w celu uzyskania prostych potrzeb blokujących o wysokiej częstotliwości.

Techniczne głębokie nurkowanie

Mutexy zwykle wykorzystują operacje atomowe, takie jak porównanie i wyposażanie się (CAS) do blokowania i odblokowania w przestrzeni użytkowników i wprowadzają jądro tylko wtedy, gdy nastąpi rywalizacja o blokowanie wątku. To minimalizuje przełączanie kontekstowe i narzuty w niekontacowanym przypadku.

Kanały wdrażają kolejki FIFO dla wiadomości i są często wspierane przez bufory, które mogą zmienić rozmiar. Wysyłanie kanału polega na sprawdzeniu, czy odbiornik jest gotowy, kopiowanie danych do bufora lub blokowanie oraz planowanie odbierania Goroutine. Te kroki dodają kosztów, które mnożą się z częstotliwością operacyjną.

Mutexes śpią, walcząc o wątkach i utrzymują kolejkę, więc tylko jedna nić budzi się na raz. Kanały mogą budzić wiele gorutin, gdy wiadomości stają się dostępne, co prowadzi do bardziej złożonych kosztów planowania i przełączania kontekstu.

Wniosek

Podsumowując, muteksy są znacznie szybsze niż kanały w scenariuszach wymagających szybkiego, prostego i częstego wspólnego mutacji stanu o niskiej rywalizacji lub krótkich sekcjach krytycznych. Ich lekka implementacja operacji atomowej, efektywne blokowanie jądra i budzenie wątków oraz bezpośredni dostęp do pamięci zapewniają doskonałą wydajność w porównaniu do planowania, kopiowania i przekazywania komunikatów. Kanały lepiej nadają się do komunikowania złożonej pracy i koordynowania goutinów, ale kosztują szybkość synchronizacji surowej.

To zrozumienie jest poparte wieloma testami porównawczymi i praktycznymi przykładami z systemów produkcyjnych i wyników eksperymentalnych. Zatem decyzja między muteksami a kanałami powinna opierać się na charakterystyce obciążenia i potrzebach synchronizacji, z mutexesami preferowanymi dla surowej prędkości w ochronie wspólnej pamięci i kanałach zarezerwowanych dla wzorców koordynacji i komunikacji wyższego poziomu.