Czy są procesory, które wykonują tę możliwą optymalizację zapisu w pamięci podręcznej L1?

9

Gdy procesor z pamięcią podręczną L1 dokonuje zapisu, zwykle dzieje się tak, że (zakładając, że linia pamięci podręcznej, do której pisze, jest już w pamięci podręcznej L1) pamięć podręczna (oprócz aktualizacji danych) oznacza tę linię pamięci jako brudną , i wypisze wiersz ze zaktualizowanymi danymi w późniejszym czasie.

Jedną z możliwych optymalizacji byłoby porównanie pamięci podręcznej z treścią zapisu i poprzednią zawartością pamięci podręcznej, a jeśli są takie same, nie zaznaczaj linii jako brudnej. Ponieważ może to pozwolić pamięci podręcznej na uniknięcie czasami zapisów zwrotnych, widzę, jak producent procesora może uznać to za warte bramek potrzebnych do wykonania tej logiki.

Moje pytanie: czy są procesory, które przeprowadzają tę optymalizację?

Tło, dlaczego pytam: piszę kod, który musi mieć stały dostęp do pamięci; to znaczy, ktoś, kto jest w stanie wsłuchać się w zachowanie pamięci podręcznej, nie powinien być w stanie wydedukować tego, co robię. Niektóre z moich dostępów to zapisy i w oczywisty sposób, aby wdrożyć ten kod, wiele zapisów będzie zapisywać te same dane, które już tam są. Muszę robić zapisy, ponieważ w zależności od danych dane, które piszę, mogą, ale nie muszą być takie same, i ważne jest, aby wykonać tę samą akcję niezależnie od tego. Jeśli procesor optymalizuje się, nie pisząc „zapisu bez zmian”, oznaczałoby to, że zachowanie pamięci podręcznej będzie się różnić w zależności od tego, co robię, co podważyłoby mój cel.

Czy jest więc procesor, który próbuje zoptymalizować zapis w ten sposób?

ponczo
źródło
11
Mówi się, że istnieją dwa naprawdę trudne problemy w informatyce: unieważnienie pamięci podręcznej, dobre nazywanie rzeczy i błędy indywidualne. To przykład, dlaczego pierwszy z nich jest trudny.
Mason Wheeler,
@poncho mówisz, że „ktoś, kto jest w stanie wsłuchać się w zachowanie pamięci podręcznej, nie powinien być w stanie wydedukować tego, co robię”. Teraz, jeśli niektóre procesory zaimplementują tę funkcję „inteligentnego zapisu”, która nie unieważnia pamięci podręcznej, chyba że dane są naprawdę aktualizowane, to przechodząc o jeden poziom dalej od procesora w hierarchii pamięci, można obserwować ruch / synchronizację różnice między pisaniem rzeczywistym a tekstem pozorowanym. Czy o to się martwisz?
TheCodeArtist
@poncho Twoje prawdziwe pytanie wydaje się dotyczyć wprowadzenia lepszego uprzywilejowanego / bezpiecznego trybu, który nie powoduje wycieku informacji o użytkowaniu. Może powinieneś o to zapytać? ...
TheCodeArtist
1
@TheCodeArtist: no cóż, opublikowano kryptograficzne ataki sidechannel, w których procedura szyfrowania może zostać zaatakowana przez inny program działający na innym rdzeniu tego samego procesora, poprzez monitorowanie przez program ataku wspólnej pamięci podręcznej. Wierzę, że taki program mógłby potencjalnie wykryć, czy linie pamięci podręcznej L1 zostały opróżnione, a zatem mógłby wydedukować informacje o programie, który mnie interesuje, jeśli procesor przeprowadzi optymalizację omawianą. Nie mówię o „trybie bezpiecznym”, ponieważ nie zakładam możliwości modyfikowania procesora lub systemu operacyjnego.
ponczo
4
Nawet jeśli jest to prawda dzisiaj, nie ma gwarancji, że jutro będzie to prawdą.
pjc50,

Odpowiedzi:

4

Po wielu godzinach poszukiwań nie byłem w stanie znaleźć procesora, który korzysta z tej konkretnej optymalizacji. Większość wspomnianych optymalizacji dotyczy zwykle trafień / braków z operacjami odczytu / zapisu i dostępu do danych:

(strony 7 i) https://cseweb.ucsd.edu/classes/fa14/cse240A-a/pdf/08/CSE240A-MBT-L15-Cache.ppt.pdf

Nie oznacza to jednak, że nie można przeprowadzić tej optymalizacji. Zasadniczo możliwy jest programowy dostęp do wielkości linii pamięci podręcznej procesora. Możliwe jest również uzyskanie dostępu do bieżących wartości w rejestrach pamięci podręcznej - ale jest to nieco niebezpieczne. Jeśli uzyskasz dostęp do niewłaściwych rejestrów w złym momencie, możesz manipulować przy rejestrach związanych z uruchomionym programem. Lub możesz przypadkowo zmodyfikować zawartość wierszy, które próbujesz odczytać.

Uzyskiwanie bieżącej wartości w pamięci podręcznej rejestru

Ponadto wszystkie teoretyczne rozwiązania wymagają pewnej formy implementacji oprogramowania (asemblera). Najbliższe, jakie znalazłem, dotyczy architektury ARM, która wydaje się pozwalać na manipulację pamięcią podręczną. Oprócz tego musisz także znać rozmiar linii pamięci podręcznej dla żądanego procesora. Możesz ostrożnie odczytać zawartość pamięci podręcznej do drugiej lokalizacji w pamięci, w przyrostach wielkości wiersza, i porównać ją z danymi, które mają zostać zapisane w rejestrach (w tym przypadku liniami pamięci podręcznej L1).

Czytaj zawartość pamięci podręcznej procesora

Stamtąd możesz opracować system oparty na oprogramowaniu, który zapobiega identycznym przepisywaniu. Chociaż jest to nieco uproszczone, dzieje się tak, ponieważ rozwiązanie musi mieć zastosowanie do każdego istniejącego procesora.

Inna możliwość, którą znalazłem, była związana ze spójnością pamięci podręcznej:

Odpowiedni fragment artykułu z Wikipedii na temat spójności

Głównym punktem, który zwrócił moją uwagę, w związku z tym problemem, był opis Snarfing:

Jest to mechanizm, w którym kontroler pamięci podręcznej obserwuje zarówno adres, jak i dane, próbując zaktualizować własną kopię lokalizacji w pamięci, gdy drugi master modyfikuje lokalizację w pamięci głównej. Gdy obserwowana jest operacja zapisu w lokalizacji, w której znajduje się kopia pamięci podręcznej, kontroler pamięci podręcznej aktualizuje swoją własną kopię lokalizacji pamięci tymczasowej o nowe dane.

Innymi słowy, prawdopodobnie istnieją już mechanizmy. Tyle, że mogą nie zostać użyte do optymalizacji, którą zasugerowałeś. Będziesz musiał wdrożyć oprogramowanie, które przeprowadziło porównanie odczytu / zapisu.

Społeczność
źródło
Możliwe jest również uzyskanie dostępu do bieżących wartości w rejestrach pamięci podręcznej - ale jest to nieco niebezpieczne. Huh, to nie ma sensu. Masz na myśli rejestry procesora? Generowany przez kompilator lub ręcznie pisany kod asm używa rejestrów do przechowywania wartości, na których działa ...
Peter Cordes
Jeśli próbujesz zaimplementować to w oprogramowaniu, kompilator wygeneruje kod, który robi to if (mem != x) { mem = x; }zamiast mem = x;. Jest to tylko czasami optymalizacja współdzielonych linii pamięci podręcznej w programie wielowątkowym, ponieważ zapis zakłóca odczyt innych wątków.
Peter Cordes
1
„snarfing” nie ma z tym nic wspólnego. To tylko pasywne węszenie. Pamięci podręczne procesorów używają MESI, aby mogły mieć spójne pamięci podręczne zapisu.
Peter Cordes
@PeterCordes Jeśli uważasz moją odpowiedź za niesmaczną, przepraszam. Wydaje się jednak, że w tej sprawie masz więcej wglądu niż ja. Dlaczego więc sam nie odpowiedzieć na pytanie? Moja odpowiedź była oczywiście niewystarczająca według twoich standardów ...
Zrobiłem to, w prawie duplikacie tego pytania na SO .
Peter Cordes
3

Zapisywanie do pamięci podręcznej L1 jest operacją bardzo krytyczną pod względem czasu.

Zapisywanie dokładnie tych samych danych wydaje się raczej rzadkie. Optymalizacja, która przyspiesza rzeczy w tym konkretnym przypadku, nie da w sumie dużo przyspieszenia.

Z drugiej strony ta optymalizacja wymaga porównania starych danych i nowych danych przy każdym zapisie do pamięci podręcznej. Co gorsza, to fakt, że dane, które mają być zapisane, muszą być faktycznie dostępne w momencie zapisu!

Zazwyczaj tak nie jest w przypadku nowoczesnego procesora. Dane, które należy zapisać, wciąż mogą być na przykład obliczane. Pamięć podręczna może nadal działać, w razie potrzeby załadować linię pamięci podręcznej, oznaczyć linię pamięci podręcznej jako zmodyfikowaną itd., Nawet przed zakończeniem obliczeń. Wszystkie księgowanie można już wykonać, z wyjątkiem faktycznej modyfikacji linii pamięci podręcznej. Jeśli chcesz porównać nowo zapisane wyniki i stare dane linii pamięci podręcznej, nie jest to możliwe.

Na przykład, jeśli masz kod C a [i] = x / y; podział x / y zajmuje bardzo dużo czasu na większości procesorów. Jednak większość pracy potrzebnej do obsługi przechowywania wyniku w [i] miała miejsce na długo przed zakończeniem podziału; jedyne, czego brakuje, to przeniesienie ośmiu bajtów wyników do linii pamięci podręcznej. Operacja opróżnienia linii pamięci podręcznej automatycznie zaczeka na zakończenie podziału. Operacja odczytująca [i] prawdopodobnie zostanie przekierowana, aby uzyskać wynik bezpośrednio z dzielnika.

gnasher729
źródło
Pamięć podręczna wykorzystująca MESI do zachowania spójności może nadal wykonywać RFO, ale jeśli dane będą porównywane tak samo, gdy będą gotowe, pozostaw linię w stanie Wyłączne zamiast Zmodyfikowane. Prawdziwym powodem, dla którego nie odbywa się to sprzętowo, jest to, że kosztuje dodatkowe odczyty pamięci podręcznej, gdy dane zobowiązują się do buforowania, i wymagałoby pewnego rodzaju atomowych cykli odczytu / porównania / zapisu (z opcjonalnym ustawieniem zabrudzonego bitu), co powoduje, że jest on do bani implementacja potokowa.
Peter Cordes,
1

Jedną z możliwych optymalizacji byłoby porównanie pamięci podręcznej z treścią zapisu i poprzednią zawartością pamięci podręcznej, a jeśli są takie same, nie zaznaczaj linii jako brudnej

Czy taka optymalizacja nie zwiększy dwukrotnie czasu procesora potrzebnego na zapisanie czegoś w pamięci podręcznej? Ponieważ do każdego wiersza zapisu w pamięci podręcznej będzie teraz towarzyszyć operacja porównania, która nie jest wolna.

Tak więc optymalizacja będzie teraz zależeć od bardzo niejasnego czynnika: ile razy przeciętne oprogramowanie przepisuje swoją pamięć podręczną tymi samymi danymi.

Vladislav Rastrusny
źródło
To porównanie zostanie zaimplementowane w logice procesora. Nie wymagałoby to dodatkowej operacji procesora, ale czas sygnału może się wydłużyć, co może stanowić problem lub nie.
ziggystar
@ziggystar Cóż, nie jestem mistrzem sprzętu, ale przyzwyczaiłem się do myśli, że wszystko kosztuje. Podobnie jak operacja porównania z linią pamięci podręcznej. To może być szybkie. Ale to wciąż kosztuje. I myślę, że realizatorzy postanowili nie płacić. Może być nawet po zastanowieniu i pomiarze.
Vladislav Rastrusny
1
Ale mówisz o czasie, w którym kosztem może być tylko wzrost liczby bramek.
ziggystar
1
@ziggystar: To nie tylko więcej bram. Gdy dane są wysyłane do pamięci podręcznej, zwykle proces wysyłania danych może oznaczyć linię pamięci podręcznej jako zmodyfikowaną. Dzięki tej „optymalizacji” zarówno stare, jak i nowe dane muszą przejść przez te bramki, co spowoduje pewne opóźnienie, i dopiero wtedy pamięć podręczna może zostać unieważniona. Trzeba to wszystko wycisnąć w jednym cyklu procesora, w przeciwnym razie zapis do linii pamięci podręcznej zajmuje nagle dwa cykle. A teraz, aby skomplikować sprawę, zastanów się, co się stanie, gdy napiszę osiem kolejnych słów do wiersza pamięci podręcznej.
gnasher729,
1
I każdy z tych zapisów opóźnia decyzję, czy linia bufora jest modyfikowana. Kiedy więc nastąpi drugi zapis, linia bufora nie wie, czy jest zmodyfikowana, czy nie (jeszcze). Bedzie fajnię.
gnasher729,