Kluczowym punktem jest przysłówek lokalnie w cytowanym zdaniu „nie wykonuje aż wszystkie wcześniejsze instrukcje zakończyły lokalnie”.
Nie byłem w stanie znaleźć jasnej definicji "kompletnie lokalnie" całego zestawu instrukcji Intela, moje spekulacje wyjaśniono poniżej.
Aby zostać zakończone lokalnie instrukcja musi mieć to wyjście obliczane i dostępne dla innych instrukcji dalej w łańcuchu zależności. Ponadto wszelkie skutki uboczne tej instrukcji muszą być widoczne wewnątrz rdzenia.
Aby być ukończonym globalnie, instrukcja musi mieć efekty uboczne widoczne dla innych składników systemu (takich jak inne procesory).
Jeśli nie kwalifikujemy się do rodzaju "kompletności", o której mówimy, oznacza to, że nie ma to znaczenia lub jest ukryte w kontekście.
Dla wielu instrukcji wykonywanych lokalnie i globalnie, jest taki sam.
Na przykład, aby załadować , na przykład, w celu dokończenia lokalnie, niektóre dane muszą zostać pobrane z pamięci lub pamięci podręcznych. Jest to równoznaczne z ukończeniem globalnym, ponieważ nie możemy oznaczyć obciążenia, jeśli nie odczytujemy najpierw z hierarchii pamięci.
Dla sklepu sklep sytuacja jest jednak inna.
procesory
Intel mają Store Buffer obsłużyć zapisuje w pamięci, z rozdziału 11.10 podręcznika 3:
Intel 64 i procesorów IA-32 czasowego przechowywania każdego zapisu (Store) do pamięci w bufor do przechowywania. Bufor sklepu poprawia wydajność procesora, umożliwiając procesorowi kontynuowanie wykonywania instrukcji bez konieczności oczekiwania na zapis do pamięci i/lub do pamięci podręcznej. Umożliwia także opóźnianie zapisów w celu bardziej efektywnego wykorzystania cykli magistrali dostępu do pamięci.
Sklep można uzupełnić lokalnie, umieszczając go w buforze sklepu, z perspektywy rdzenia zapis jest taki, jak w pamięci.
Obciążenie z tego samego rdzenia sklepu, w określonych okolicznościach, może nawet odczytać tę wartość (nazywa się to Store Forwarding).
Do uzupełnienia globalnie jednak sklep musi być wyczerpany z bufora sklepu.
Wreszcie jest obowiązkowe, aby dodać, że magazyn buforowy jest odprowadzana przez szeregowania instrukcji:
zawartość bufora sklepie są zawsze odprowadzana do pamięci w następujących sytuacjach:
• (P6 i nowsza Procesor tylko rodziny) Kiedy wykonywana jest instrukcja serializacyjna.
• (tylko Pentium III i nowsze rodziny procesorów) Podczas korzystania z instrukcji SFENCE do zamawiania sklepów.
• (tylko modele Pentium 4 i nowsze rodziny procesorów) Podczas korzystania z instrukcji EFENCE do zamawiania sklepów.
robione z wprowadzeniem, zobaczmy co lfence
, mfence
i sfence
zrobić:
LFENCE nie wykonuje aż wszystkie wcześniejsze instrukcje zakończyły lokalnie, a nie później nauka rozpoczyna realizację aż LFENCE kończy.
MFENCE wykonuje operację serializacji na wszystkich instrukcjach load-from-memory i store-to-memory, które zostały wydane przed instrukcją MFENCE. Tryb MFENCE nie przekształca serialu w strumień instrukcji.
SFENCE wykonuje operację serializacji na wszystkich instrukcjach zapisywania do pamięci, które zostały wydane przed instrukcją SFENCE.
Więc lfence
jest słabsza forma serializacji że nie odprowadza sklepu Buffer, ponieważ skutecznie serializacji instrukcji lokalnie, wszystkie ładunki przed nim musi być zakończone przed jej zakończeniem.
sfence
serializuje tylko sklepy, zasadniczo nie pozwala procesowi na wykonanie kolejnego sklepu, dopóki nie zostanie wycofany sfence
. Drenuje również bufor Sklepu.
mfence
jest nie prosta kombinacja tych dwóch, ponieważ nie jest szeregowania w klasycznym tego słowa znaczeniu, jest to sfence
że również zapobiec przyszłym ładunki mają być wykonane.
Warto może nic że sfence
został wprowadzony pierwszy i pozostałe dwójki przyszedł później, aby osiągnąć bardziej precyzyjną kontrolę nad porządkowania pamięci.
Wreszcie, zostałem użyty do zamknięcia instrukcji rdtsc
między dwiema instrukcjami: lfence
, aby upewnić się, że nie było możliwości zmiany kolejności "do tyłu" i "do przodu".
Jestem jednak pewien, że ta technika jest dobra.
Dzięki za skomplikowaną odpowiedź. Więc jeśli dobrze rozumiem, LFENCE nie drenuje bufora magazynu, ale powoduje, że procesor czeka, aż wszystkie poprzednie instrukcje ładowania i przechowywania zakończą się lokalnie. W takim przypadku nie możemy polegać na pomiarze czasu (RDTSC) na końcu naszego kodu testu porównawczego? Ponieważ chcesz upewnić się, że zapisy zostały wykonane globalnie (przepłukane do pamięci) przed pomiarem czasu. Dzięki. –
'lfence' może być użyte do pomiaru * jeśli nie chcesz czekać *, aby sklepy stały się widoczne na całym świecie. Pisanie do pamięci wymaga wielu cykli, a jeśli nie będziesz dokładnie zapisywać w pamięci podręcznej, otrzymasz niespójne wyniki. Zwykle jeden urlop zapisuje do pamięci test porównawczy, chyba że chcesz jawnie je przetestować. W takim przypadku użyj 'lfence' z' sfence' lub serializującą instrukcję, która nie spowoduje nadpisania potrzebnych rejestrów. –
Ma sens. Dziękuję bardzo. –