Trzeba przyznać, że nie rozumiem. Załóżmy, że masz pamięć ze słowem o długości 1 bajta. Dlaczego nie można uzyskać dostępu do 4-bajtowej zmiennej w pojedynczym dostępie do pamięci na niezaangażowanym adresie (tzn. Nie można podzielić przez 4), jak ma to miejsce w przypadku wyrównanych adresów?
196
Odpowiedzi:
Jest to ograniczenie wielu podstawowych procesorów. Zwykle można to obejść, wykonując 4 nieefektywne jednobajtowe pobieranie zamiast jednego wydajnego pobierania słów, ale wielu specyfikatorów języków zdecydowało, że łatwiej byłoby po prostu je zakazać i wymusić wyrównanie wszystkiego.
Ten link zawiera znacznie więcej informacji, które odkrył OP.
źródło
Podsystem pamięci w nowoczesnym procesorze jest ograniczony do dostępu do pamięci w stopniu szczegółowości i wyrównania wielkości słowa; dzieje się tak z wielu powodów.
Prędkość
Nowoczesne procesory mają wiele poziomów pamięci podręcznej, przez które dane muszą być pobierane; obsługa odczytów jednobajtowych spowodowałaby, że przepustowość podsystemu pamięci byłaby ściśle związana z przepustowością jednostki wykonawczej (zwanej także procesorem); wszystko to przypomina, w jaki sposób tryb PIO został wyprzedzony przez DMA z wielu tych samych powodów na dyskach twardych.
Procesor zawsze odczytuje rozmiar słowa (4 bajty na 32-bitowym procesorze), więc gdy wykonasz niezrównany dostęp do adresu - na procesorze, który go obsługuje - procesor odczyta wiele słów. Procesor odczyta każde słowo pamięci, które mieści się w żądanym adresie. Powoduje to zwiększenie do dwukrotności liczby transakcji pamięci wymaganych do uzyskania dostępu do żądanych danych.
Z tego powodu bardzo łatwo można odczytać dwa bajty niż cztery. Załóżmy na przykład, że masz strukturę pamięci, która wygląda następująco:
W 32-bitowym procesorze najprawdopodobniej byłby wyrównany, jak pokazano tutaj:
Procesor może odczytać każdego z tych członków w jednej transakcji.
Załóżmy, że masz spakowaną wersję struktury, być może z sieci, w której została zapakowana w celu zwiększenia wydajności transmisji; może wyglądać mniej więcej tak:
Czytanie pierwszego bajtu będzie takie samo.
Gdy poprosisz procesor o podanie 16 bitów z 0x0005, będzie musiał odczytać słowo z 0x0004 i przesunąć w lewo o 1 bajt, aby umieścić go w rejestrze 16-bitowym; dodatkowe prace, ale większość może sobie z tym poradzić w jednym cyklu.
Gdy poprosisz o 32 bity od 0x0001, otrzymasz wzmocnienie 2X. Procesor wczyta z 0x0000 do rejestru wyników i przesunie w lewo o 1 bajt, a następnie wczyta ponownie z 0x0004 do rejestru tymczasowego, przesunie w prawo o 3 bajty, a następnie
OR
z rejestrem wyników.Zasięg
W przypadku dowolnej przestrzeni adresowej, jeśli architektura może założyć, że 2 LSB mają zawsze wartość 0 (np. Maszyny 32-bitowe), może uzyskać dostęp do 4 razy większej pamięci (2 zapisane bity mogą reprezentować 4 różne stany) lub taką samą ilość pamięci z 2 bitami na coś w rodzaju flag. Usunięcie 2 LSB z adresu dałoby wyrównanie do 4 bajtów; nazywany także krokiem 4 bajtów. Za każdym razem, gdy adres jest zwiększany, efektywnie zwiększa bit 2, a nie bit 0, tzn. Ostatnie 2 bity zawsze będą nadal
00
.Może to nawet wpłynąć na fizyczną konstrukcję systemu. Jeśli magistrala adresowa potrzebuje 2 bitów mniej, procesor może mieć o 2 mniej pinów i o 2 mniej śladów na płytce drukowanej.
Atomowość
CPU może działać atomowo na wyrównanym słowie pamięci, co oznacza, że żadna inna instrukcja nie może przerwać tej operacji. Ma to kluczowe znaczenie dla prawidłowego działania wielu struktur danych bez blokady i innych paradygmatów współbieżności .
Wniosek
System pamięci procesora jest nieco bardziej złożony i zaangażowany niż tutaj opisano; pomocna może być dyskusja na temat tego, w jaki sposób procesor x86 adresuje pamięć (wiele procesorów działa podobnie).
Istnieje wiele innych korzyści związanych z dostosowaniem pamięci, które można przeczytać w tym artykule IBM .
Podstawowym zastosowaniem komputera jest przekształcanie danych. Nowoczesne architektury i technologie pamięci zostały zoptymalizowane na przestrzeni dziesięcioleci, aby ułatwić uzyskiwanie większej ilości danych, wprowadzanie, wyprowadzanie oraz pomiędzy większą liczbą szybszych jednostek wykonawczych - w wysoce niezawodny sposób.
Bonus: Skrytki
Innym wyrównaniem do wydajności, o którym wspominałem wcześniej, jest wyrównanie w liniach pamięci podręcznej, które są (na przykład w niektórych procesorach) 64B.
Aby uzyskać więcej informacji o tym, ile wydajności można uzyskać dzięki wykorzystaniu pamięci podręcznej, zobacz Galerię efektów pamięci podręcznej procesora ; z tego pytania na temat rozmiarów linii pamięci podręcznej
źródło
możesz z niektórymi procesorami ( nehalem może to zrobić ), ale wcześniej cały dostęp do pamięci był wyrównany na linii 64-bitowej (lub 32-bitowej), ponieważ szyna ma szerokość 64 bitów, trzeba było pobrać 64 bitów na raz , i znacznie łatwiej było pobrać je w wyrównanych „fragmentach” 64 bitów.
Więc jeśli chcesz uzyskać pojedynczy bajt, pobrałeś 64-bitowy fragment, a następnie zamaskowałeś bity, których nie chciałeś. Łatwo i szybko, jeśli twój bajt był na prawym końcu, ale jeśli był w środku tego 64-bitowego fragmentu, będziesz musiał maskować niechciane bity, a następnie przenieść dane we właściwe miejsce. Co gorsza, jeśli potrzebna była zmienna 2-bajtowa, ale została ona podzielona na 2 porcje, wymagało to podwójnego wymaganego dostępu do pamięci.
Ponieważ wszyscy uważają, że pamięć jest tania, po prostu sprawili, że kompilator wyrównał dane do wielkości porcji procesora, dzięki czemu kod działa szybciej i wydajniej kosztem zmarnowanej pamięci.
źródło
Zasadniczo powodem jest to, że magistrala pamięci ma określoną długość, która jest znacznie, znacznie mniejsza niż rozmiar pamięci.
Tak więc procesor odczytuje z wbudowanej pamięci podręcznej L1, która obecnie często wynosi 32 KB. Ale magistrala pamięci, która łączy pamięć podręczną L1 z procesorem, będzie miała znacznie mniejszą szerokość rozmiaru linii pamięci podręcznej. Będzie to rzędu 128 bitów .
Więc:
Niewłaściwe dostępy będą czasami nakładać się na dwie linie pamięci podręcznej, a to będzie wymagało całkowicie nowego odczytu pamięci podręcznej w celu uzyskania danych. Może nawet przeoczyć drogę do DRAM.
Co więcej, część procesora będzie musiała stać na głowie, aby złożyć pojedynczy obiekt z tych dwóch różnych linii pamięci podręcznej, z których każda zawiera fragment danych. W jednej linii będą to bity bardzo wysokiego rzędu, w drugiej bity bardzo niskiego rzędu.
Zostanie dedykowany sprzęt w pełni zintegrowany z potokiem, który obsługuje przenoszenie wyrównanych obiektów na niezbędne bity szyny danych procesora, ale takiego sprzętu może brakować w przypadku niedopasowanych obiektów, ponieważ prawdopodobnie bardziej sensowne jest użycie tych tranzystorów do przyspieszenia poprawnie zoptymalizowanej programy.
W każdym razie drugi odczyt pamięci, który czasami jest konieczny, spowolniłby potok, bez względu na to, ile specjalnego sprzętu (hipotetycznie i głupio) było przeznaczone do łatania źle wyrównanych operacji pamięci.
źródło
@joshperry udzielił doskonałej odpowiedzi na to pytanie. Oprócz jego odpowiedzi mam kilka liczb, które pokazują graficznie opisane efekty, szczególnie wzmocnienie 2X. Oto link do arkusza kalkulacyjnego Google pokazującego, jak wyglądają efekty różnych dopasowań słów. Ponadto znajduje się link do listy Github z kodem testu. Kod testowy jest dostosowany z artykułu napisanego przez Jonathana Rentzscha, do którego odwołuje się @joshperry. Testy przeprowadzono na Macbooku Pro z czterordzeniowym procesorem Intel Core i7 2,8 GHz 2,8 GHz i 16 GB pamięci RAM.
źródło
x
iy
współrzędne?Jeśli system z pamięcią adresowalną bajtowo ma szynę pamięci o szerokości 32 bitów, oznacza to, że istnieją efektywnie cztery bajtowe systemy pamięci, z których wszystkie są podłączone do odczytu lub zapisu tego samego adresu. Wyrównany 32-bitowy odczyt będzie wymagał informacji przechowywanych pod tym samym adresem we wszystkich czterech systemach pamięci, więc wszystkie systemy mogą dostarczać dane jednocześnie. 32-bitowy odczyt bez wyrównania wymagałby, aby niektóre systemy pamięci zwracały dane z jednego adresu, a niektóre zwracały dane z następnego wyższego adresu. Chociaż istnieją pewne systemy pamięci zoptymalizowane pod kątem spełnienia takich żądań (oprócz adresu, mają one skutecznie sygnał „plus jeden”, co powoduje, że używają adresu o jeden wyższy niż określony), jednak taka funkcja powoduje znaczne koszty i złożoność systemu pamięci;
źródło
Jeśli masz szynę danych 32-bitowy adres autobusowe linie adresowe podłączone do pamięci rozpocznie się od A 2 , więc tylko 32bit wyrównane adresy można uzyskać w jednym cyklu magistrali.
Więc jeśli rozpiętości słowo adres wyrównanie brzegowe - czyli 0 do 16/32 danych bitowych lub 1 dla 32-bitowych danych nie są zerowe, dwa cykle magistrali są wymagane w celu uzyskania danych.
Niektóre zestawy architektur / instrukcji nie obsługują niezaangażowanego dostępu i generują wyjątek przy takich próbach, więc wygenerowany przez kompilator niepasowany kod dostępu wymaga nie tylko dodatkowych cykli magistrali, ale dodatkowych instrukcji, co czyni go jeszcze mniej wydajnym.
źródło
Na PowerPC możesz bez problemu załadować liczbę całkowitą z nieparzystego adresu.
Sparc i I86 oraz (tak myślę) Itatnium podnoszą wyjątki sprzętowe, gdy spróbujesz tego.
Jedno obciążenie 32-bitowe w porównaniu do czterech obciążeń 8-bitowych nie zrobi dużej różnicy w większości nowoczesnych procesorów. To, czy dane są już w pamięci podręcznej, czy nie, będzie miało znacznie większy efekt.
źródło