2013-06-07 25 views
5

Jest to ilustracja w kernel source/Documentation pamięci-barriers.txt, tak:jak jest bariera pamięci w jądrze Linux jest używany

CPU 1     CPU 2 
    ======================= ======================= 
      { B = 7; X = 9; Y = 8; C = &Y } 
    STORE A = 1 
    STORE B = 2 
    <write barrier> 
    STORE C = &B   LOAD X 
    STORE D = 4    LOAD C (gets &B) 
          LOAD *C (reads B) 

Bez interwencji procesora 2 mogą postrzegać wydarzenia na CPU 1 w jakiś skutecznie losowej kolejności, pomimo bariery zapisu wydanego przez CPU 1:

+-------+  :  :    :  : 
    |  |  +------+    +-------+ | Sequence of update 
    |  |------>| B=2 |-----  --->| Y->8 | | of perception on 
    |  | : +------+  \   +-------+ | CPU 2 
    | CPU 1 | : | A=1 |  \  --->| C->&Y | V 
    |  |  +------+  |  +-------+ 
    |  | wwwwwwwwwwwwwwww |  :  : 
    |  |  +------+  |  :  : 
    |  | : | C=&B |--- |  :  :  +-------+ 
    |  | : +------+ \ |  +-------+  |  | 
    |  |------>| D=4 | ----------->| C->&B |------>|  | 
    |  |  +------+  |  +-------+  |  | 
    +-------+  :  :  |  :  :  |  | 
            |  :  :  |  | 
            |  :  :  | CPU 2 | 
            |  +-------+  |  | 
     Apparently incorrect ---> |  | B->7 |------>|  | 
     perception of B (!)  |  +-------+  |  | 
            |  :  :  |  | 
            |  +-------+  |  | 
     The load of X holds ---> \  | X->9 |------>|  | 
     up the maintenance   \  +-------+  |  | 
     of coherence of B    ----->| B->2 |  +-------+ 
              +-------+ 
              :  : 

nie rozumiem, ponieważ mamy barierę zapisu, więc wszelkie s tore musi zadziałać, gdy C = & B zostanie wykonane, co oznacza, że ​​B będzie równe 2. Dla CPU 2, B powinno być 2, gdy uzyska wartość C, która jest & B, dlaczego miałaby postrzegać B jako 7. Jestem naprawdę zdezorientowany.

Odpowiedz

8

Kluczem brakujący punkt jest błędne założenie, że dla sekwencji:

LOAD C (gets &B) 
LOAD *C (reads B) 

pierwszy ładunek musi poprzedzać drugi ładunek. Słabo zamówione architekturze może działać „jak gdyby” dodaje się:

LOAD B (reads B) 
LOAD C (reads &B) 
if(C!=&B) 
    LOAD *C 
else 
    Congratulate self on having already loaded *C 

spekulatywny „Load B” może się zdarzyć, na przykład, ponieważ B był na tej samej linii pamięci podręcznej niektórych innych zmiennej wcześniejszego zainteresowania lub sprzętu prefetching złapał go.

+0

Bardzo zwięzłe i prawo do punktu – dspjm

6

W sekcji dokumentu zatytułowanej „czego nie można założyć o barierach pamięć?”:

nie ma gwarancji, że którykolwiek z pamięci dostępów określony przed barierą pamięci będzie kompletny przez uzupełnienie bariery pamięciowej instrukcja; można uznać, że bariera rysuje linię w tej kolejce dostępu do procesora, której dostęp do odpowiedniego typu nie może przekroczyć.

i

Nie ma żadnej gwarancji, że CPU będzie widać poprawną kolejność efektów z dostępów drugiego CPU, nawet jeśli drugi CPU wykorzystuje pamięć barierę, chyba pierwszy Procesor także używa używa pasującej bariery pamięci (patrz podsekcja na temat "Parowania SMP Barier").

bariery Co pamięci zrobić (w bardzo uproszczony sposób, oczywiście), to upewnić się ani kompilator ani sprzętu w CPU wykonywać żadnych sprytnych prób porządkowania obciążenia (lub sklep) operacje po drugiej stronie bariery, i że Procesor prawidłowo postrzega zmiany w pamięci dokonane przez inne części systemu. Jest to konieczne, gdy ładunki (lub magazyny) mają dodatkowe znaczenie, np. Blokowanie zamka przed uzyskaniem dostępu do tego, co blokujemy. W takim przypadku pozwolenie kompilatorowi/procesorowi na zwiększenie dostępu poprzez zmianę kolejności jest niebezpieczne dla prawidłowego działania naszego programu.

Po przeczytaniu tego dokumentu musimy zachować dwie rzeczy na uwadze:

  1. To obciążenie oznacza przekazywanie wartości z pamięci (cache) lub do rejestru procesora.
  2. To, że jeśli procesory nie współużytkują pamięci podręcznej (lub w ogóle nie mają pamięci podręcznej), możliwe jest, że ich systemy pamięci podręcznej będą na chwilę naszą zsynchronizowaną.

Fakt # 2 jest jednym z powodów, dla których jeden procesor może odbierać dane inaczej niż inne. Systemy pamięci podręcznej są zaprojektowane tak, aby zapewnić dobrą wydajność i spójność w ogólnym przypadku, ale mogą potrzebować pomocy w konkretnych przypadkach, takich jak te zilustrowane w dokumencie.

Ogólnie, jak sugeruje dokument, bariery w systemach z więcej niż jednym procesorem powinny być sparowane, aby zmusić system do zsynchronizowania percepcji obu (lub wszystkich uczestniczących) procesorów. Wyobraź sobie sytuację, w której jeden procesor kończy ładowanie lub przechowuje, a pamięć główna jest aktualizowana, ale nowe dane nie zostały jeszcze przesłane do pamięci podręcznej drugiego procesora, co powoduje brak spójności w obu procesorach.

Mam nadzieję, że to pomoże. Sugerowałabym przeczytanie memory-barriers.txt ponownie, mając na uwadze tę kwestię, a szczególnie sekcję zatytułowaną "EFEKTY PROCESU CACHE CPU".