2015-04-26 10 views
8

Jaki jest cel prefiksu x86 LOCK, jeśli protokół MESI uniemożliwia zapisywanie innych rdzeni do "wyłącznych" danych będących własnością prywatną?Prefiks LOCK kontra protokół MESI?

Jestem trochę zmieszany z tym, co zapewnia LOCK i co zapewnia MESI?

Rozumiem, że protokół MESI polega na zapewnieniu, że rdzenie wszystkie widzą spójny stan pamięci, ale jak rozumiem, to także zapobiega zapisywaniu rdzeni do pamięci, do której inny rdzeń już pisze.

+2

Rozpatrz różnicę między zablokowanym a odblokowanym przyrostem: jeśli dwa rdzenie jednocześnie zwiększą wartość 0 w pamięci, obie zdecydują się zapisać 1 w pamięci. Koherencja pamięci podręcznej nie zapobiega utracie jednej z aktualizacji. –

+0

@KerrekSB przepraszam, nie bardzo rozumiem, co masz na myśli. Czy buforowanie spójności nie byłoby możliwe tylko dla jednego z rdzeni będących własnością zapisywanej pamięci podręcznej? Dlatego jeśli drugi rdzeń został zmodyfikowany w celu zmodyfikowania pamięci podręcznej, podczas gdy pierwszy był inkrementujący, MESI uniemożliwiłoby zapis do momentu, aż pierwszy rdzeń dokonałby inkrementacji? – user997112

+7

Inkrementowanie nie jest operacją atomową. Najpierw oba rdzenie odczytują tę samą wartość (0) z czystej linii pamięci podręcznej. Następnie obaj decydują o obliczeniu nowej wartości (1). Następnie oba zapisują wartość z powrotem. Na tym etapie pisania spójność pamięci podręcznej nie pomaga, ponieważ zapis na pamięć nie jest bezpośrednio zależny od spójności (tylko * czytanie * z brudnych stron jest). –

Odpowiedz

-1

Tak, mylicie dwie różne rzeczy. Protokół MESI jest protokołem koherencji, który zapewnia, że ​​każdy rdzeń/procesor otrzymuje najbardziej aktualne dane z pamięci podręcznej innych procesorów (lub mem) na żądanie. Jeśli linia pamięci podręcznej znajduje się w stanie "E", oznacza to, że procesor żądający otrzymuje jeden (i tylko jeden) inny procesor z kopią tej linii. To wszystko, co robi; stan "E" w żaden sposób nie uniemożliwia procesorowi żądającemu dostępu do danych; po prostu stwierdza, że ​​tylko jeden procesor ma kopię danych (i ta kopia jest również zgodna z tą, która jest w pamięci). Tak więc, jeśli rdzeń zażąda danych, które są w stanie "E", rdzeń otrzyma jego kopię. Druga kopia, która była w "E", zostanie zmieniona w zależności od tego, czy rdzeń zażąda kopii "pisania" czy "czytania". Jeśli zostanie poproszony o zapisanie, stara kopia zostanie unieważniona ("I") i jeśli jest do odczytu, stara kopia zostanie umieszczona w udostępnionym stanie "S".

+0

Poprawiono funkcjonalność prefiksu LOCK. Nie ma nic złego w dwóch jednoczesnych zapisach - z LOCK lub bez niego, zobaczysz jeden z nich i jest to dowolne. –

+0

@DavidSchwartz Dziękuję David za komentarz, usunąłem tę część odpowiedzi. Nawiasem mówiąc, moja uwaga na temat prefiksu LOCK wykorzystywanego przy wdrażaniu wzajemnego wykluczenia była prawidłowa. Ponadto, co ważniejsze, kolejność zapisów NIE może być dowolna, jak wspomniano, i musi podążać za pamięcią konsekwentnie modelu architektury; w przeciwnym razie pamięć nie będzie spójna (z punktu widzenia programu i programisty). – waleed

3

Protokół MESI sprawia, że ​​pamięci podręczne są niewidoczne. Oznacza to, że programy wielowątkowe nie muszą martwić się o rdzeń odczytywania z nich stęchłych danych lub dwóch rdzeni zapisujących do różnych części linii pamięci podręcznej i otrzymujących połowę jednego zapisu, a połowę z pozostałych wysyłanych do pamięci głównej.

Jednak nie pomaga to w operacjach read-modify-write, takich jak inkrementacja, porównywanie i wymiana itd. Protokół MESI nie zatrzyma dwóch rdzeni z każdego odczytu tej samej porcji pamięci, z których każda doda jeden do niej, a następnie każdy zapisuje tę samą wartość z powrotem, zamieniając dwie inkrementy w jedną.

W przypadku nowoczesnych procesorów, prefiks LOCK blokuje linię pamięci podręcznej, aby operacja odczytu-modyfikacji-zapisu była logiczna. Są to uproszczone, ale mam nadzieję, że dadzą ci pomysł.

Unlocked przyrost:

  1. Acquire linia cache, współdzielone jest w porządku. Przeczytaj wartość.
  2. Dodaj jeden do wartości do odczytu.
  3. Uzyskaj wyłączność linii pamięci podręcznej (jeśli nie jest jeszcze E lub M) i zablokuj ją.
  4. Napisz nową wartość do linii pamięci podręcznej.
  5. Zmień linię pamięci podręcznej na zmodyfikowaną i odblokuj.

Zablokowany przyrost:

  1. Acquire linia cache wyłącznym (jeśli nie już E lub M) i zablokować go.
  2. Odczytać wartość.
  3. Dodaj do niego.
  4. Napisz nową wartość do linii pamięci podręcznej.
  5. Zmień linię pamięci podręcznej na zmodyfikowaną i odblokuj.

Zauważ różnicę? W odblokowanym inkrementu linia pamięci podręcznej jest blokowana tylko podczas operacji zapisu, tak jak wszystkie zapisy. W zablokowanym inkrementu linia pamięci podręcznej jest przechowywana w całej instrukcji, od operacji odczytu do operacji zapisu i włącznie podczas samego przyrostu.

Ponadto niektóre procesory mają inne funkcje niż pamięci podręczne pamięci, które mogą wpływać na widoczność pamięci. Na przykład niektóre procesory mają prefiks odczytu lub opublikowany bufor zapisu, który może spowodować, że operacje pamięciowe będą wykonywane poza kolejnością. W razie potrzeby prefiks LOCK (lub odpowiednia funkcjonalność na innych procesorach) również wykona wszelkie czynności, które należy wykonać, aby rozwiązać problemy z zamawianiem operacji pamięci.

+0

"Protokół MESI nie zatrzyma dwóch rdzeni z każdego odczytu tego samego fragmentu pamięci ... zamieniając dwie inkrementy w jedną." Jestem zdezorientowany tym stwierdzeniem, ponieważ wydaje się on być sprzeczny z tym, co pisze Paul McKenney [w tym artykule] (http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf). Na przykład przejścia MESI (e) i (f) na stronie 5 artykułu są powodowane przez operacje RMW. Co więcej, jeśli dwa procesory próbują jednocześnie unieważnić tę samą linię pamięci podręcznej, to zgodnie z tym artykułem, uda się umieścić linię pamięci podręcznej w stanie M przed drugą. –

+0

@ void-pointer Nie jestem pewien, co powiedzieć innym niż przeczytać ponownie moją odpowiedź. Załóżmy, że dwa procesory robią inkrement. Oboje czytają, obaj się inkrementują, potem obaj próbują pisać. W jaki sposób fakt, że jeden zapis wystąpi przed drugim, zapobiega utraconemu przyrostowi? Oczywiście, że nie. Musisz zablokować linię pamięci podręcznej podczas inkrementacji i właśnie to robi prefiks LOCK. Transition (e) to atomowa operacja "czytaj-modyfikuj i pisz", i właśnie to pytanie zadawało pytanie, dlaczego potrzebujemy. A odpowiedź brzmi: nie wystarczy zamawianie pism. –

+0

Przepraszam za głupie pytania - próbuję dowiedzieć się więcej o spójności pamięci podręcznej. Według mojej wiedzy, procesor musi mieć linię pamięci podręcznej w stanie M, aby ją zmodyfikować, a dokładnie jeden procesor może mieć określoną linię pamięci podręcznej w stanie M naraz. Nie widzę więc, jak oba procesory mogłyby jednocześnie zwiększać tę samą linię pamięci podręcznej. Jeśli dwa procesory spróbują jednocześnie RMW, to (według mojego zrozumienia) jeden "wygra" i zmusi drugiego do unieważnienia swojej kopii linii pamięci podręcznej. Przegrany musiałby wówczas dokonać read-unieważnienia, aby uzyskać wyłączność przed wykonaniem RMW. –