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:
- Acquire linia cache, współdzielone jest w porządku. Przeczytaj wartość.
- Dodaj jeden do wartości do odczytu.
- Uzyskaj wyłączność linii pamięci podręcznej (jeśli nie jest jeszcze E lub M) i zablokuj ją.
- Napisz nową wartość do linii pamięci podręcznej.
- Zmień linię pamięci podręcznej na zmodyfikowaną i odblokuj.
Zablokowany przyrost:
- Acquire linia cache wyłącznym (jeśli nie już E lub M) i zablokować go.
- Odczytać wartość.
- Dodaj do niego.
- Napisz nową wartość do linii pamięci podręcznej.
- 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.
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. –
@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
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). –