2009-11-03 19 views
6

Przeczytałem w dokumentacji Visual C++, że jest bezpieczne dla wielu wątków do odczytu z tego samego obiektu.Wiele wątków i pamięci

Moje pytanie brzmi: jak radzi sobie procesor X86-64 z wieloma rdzeniami?

Załóżmy, że masz 1 MB bloku pamięci. Czy różne wątki są dosłownie w stanie odczytać dokładnie te same dane w tym samym czasie, czy rdzenie odczytują jedno słowo na raz, a tylko jeden rdzeń może czytać dane słowo na raz?

Odpowiedz

4

Nie tylko są różne rdzenie wolno czytać z tego samego bloku pamięci, są one dopuszczone do pisania w tym samym czasie także. Jeśli jest "bezpieczny" lub nie, to zupełnie inna historia. Musisz zaimplementować jakiegoś strażnika w swoim kodzie (zwykle za pomocą semaforów lub ich pochodnych), aby chronić się przed wieloma rdzeniami walczącymi nad tym samym blokiem pamięci w sposób, na który nie pozwalasz.

O wielkości pamięci rdzeń czyta na raz, zwykle jest to wartość rejestru, 32 bity na procesorze 32-bitowym, 64-bitowe dla procesora 64-bitowego i tak dalej. Nawet streaming jest wykonywany przez dword (patrz na przykład memcpy).

O tym, jak wiele współbieżnych rdzeni jest naprawdę, każdy rdzeń wykorzystuje pojedynczą magistralę do odczytu i zapisu w pamięci, więc dostęp do dowolnych zasobów (RAM, urządzeń zewnętrznych, jednostki przetwarzania zmiennoprzecinkowego) to jedna prośba naraz, jedna rdzeń na raz. Faktyczne przetwarzanie wewnątrz rdzenia jest jednak całkowicie równoległe. Przesyłki DMA również nie blokują magistrali, równoczesne transfery są kolejkowane i przetwarzane pojedynczo (nie wierzę w to w 100%).

edytuj: tylko po to, aby wyjaśnić, w przeciwieństwie do innych odpowiedzi tutaj, mówię tylko o scenariuszu bez pamięci podręcznej. Oczywiście, jeśli pamięć zostanie zapisana w pamięci podręcznej, dostęp tylko do odczytu jest całkowicie równoległy.

+1

Każdy dostęp do pamięci ma rozmiar pamięci podręcznej = 64 bajty dla nowoczesnych procesorów. Dostęp do linii pamięci podręcznej ma charakter atomowy. Linie mogą być współdzielone przez rdzenie do czytania. – osgx

8

Jeśli naprawdę nie ma zapisów w twoim bloku 1 MB, to tak, każdy rdzeń może czytać z własnej linii pamięci podręcznej bez żadnego problemu, ponieważ nie są zapisywane żadne zapisy i dlatego nie powstają problemy z koherencją pamięci podręcznej.

W architekturze wielordzeniowej, zasadniczo istnieje pamięć podręczna dla każdego rdzenia i "Protokół koherencji pamięci podręcznej", który unieważnia pamięć podręczną w niektórych rdzeniach, które nie mają najbardziej aktualnych informacji. Myślę, że większość procesorów implementuje MOESI protocol dla spójności pamięci podręcznej.

Koherencja pamięci podręcznej to złożony temat, który został w dużej mierze omówiony (szczególnie podoba mi się kilka artykułów Joe Duffy here i here). Dyskusja toczy się wokół możliwych kar za wydajność kodu, które, choć najwyraźniej są wolne od blokady, mogą zwolnić, ponieważ protokół koherencji pamięci podręcznej kopie, aby zachować spójność w pamięciach procesorów, ale dopóki nie ma zapisów, po prostu nie ma spójność utrzymać, a tym samym nie stracić na wydajności.

Aby wyjaśnić, jak wspomniano w komentarzu, nie można uzyskać dostępu do pamięci RAM jednocześnie, ponieważ architektury x86 i x64 implementują pojedynczą magistralę, która jest współdzielona między rdzeniami za pomocą SMP, gwarantując dostęp do pamięci głównej o uczciwości. Niemniej jednak ta sytuacja jest ukryta przez każdy rdzeń pamięci podręcznej, który pozwala każdemu rdzeniu mieć własną kopię danych. Dla 1 MB danych możliwe byłoby zaistnienie na pewnym sporze, podczas gdy rdzeń zaktualizowałby pamięć podręczną, ale byłby on nieistotny.

Przydatne linki:

+0

Generalnie poprawna odpowiedź dzisiaj. Sam RAM nie może obsługiwać wielu równoczesnych wejść, ale jest to skutecznie ukrywane przez pamięci podręczne. Jeśli jednak wiele rdzeni wykonuje odczyt bez pamięci podręcznej, żądania te muszą być nadal rozstrzygane. – MSalters

Powiązane problemy