2009-09-30 12 views
7

Zgodnie z Wikipedia strona Segmentation fault, błąd magistrali może być spowodowany przez unaligned dostęp do pamięci. Artykuł podaje przykład, jak wyzwalać błąd magistrali. W tym przykładzie musimy włączyć sprawdzanie wyrównania, aby zobaczyć błąd magistrali. Co się stanie, jeśli wyłączymy sprawdzanie wyrównania?Czy brak dostępu do pamięci zawsze powoduje błędy magistrali?

Program wydaje się działać poprawnie. Mam dostęp do niewyrównanej pamięci programu i jest używany przez kilka osób, ale nikt nie zgłasza mi błędów magistrali lub innych dziwnych wyników. Jeśli wyłączymy sprawdzanie wyrównania, jaki jest efekt uboczny niewspółrzędnej pamięci?

Platformy: pracuję nad x86/x86-64. Próbowałem także mojego programu, kompilując go z "gcc -arch ppc" na Macu i działa poprawnie.

+0

Co to jest platforma, nad którym pracujesz ?? –

+0

Pavel Minaev w dużej mierze odpowiada na moje pytanie. Pracuję na x86/x86_64. Próbowałem mojego programu, kompilując go z "gcc -arch ppc" na Macu i działa poprawnie. – user172818

+0

Należy zauważyć, że niewyrównany dostęp do pamięci (a nawet po prostu przypisanie wskaźnika) jest niezdefiniowanym zachowaniem, zgodnie ze standardem C - więc kompilator zgodny z prawem może wykonać * cokolwiek *, jeśli to zrobisz (chociaż nie wszystkie kompilatory skorzystają z tej wolności). – sleske

Odpowiedz

8
  1. Dostęp do wolnej pamięci (znacznie wolniej) może być znacznie wolniejszy.

  2. Nie wszystkie platformy obsługują nawet niewyrównany dostęp - x86 i x64, ale na przykład ia64 (Itanium) nie.

  3. Kompilator może naśladować niewyrównany dostępu (VC++ robi dla wskaźników deklarowanych jako __unaligned na platformie IA64, na przykład) - wstawiając dodatkowe kontrole w celu wykrycia Nieosiowany przypadku i załadunku/magazynowanie części obiektu, który niejako na granica wyrównania osobno. Jest to nawet wolniejsze niż brak wyrównania dostępu na platformach, które natywnie go wspierają.

+0

Dzięki. Niewielu użytkowników mojego programu pracuje na ia64. Być może dlatego nie otrzymałem raportu o błędzie. – user172818

+6

Należy również dodać # 4, że system operacyjny może emulować nierównomierny dostęp do przyszłej aplikacji, przechwytując wyjątek procesora i naprawiając go (rodzaj tego, co dzieje się z błędem strony). Jest to wolniejsze niż kompilator, który w generowanym kodzie przepełnia niewyrównane poprawki. System Windows może obsługiwać to w 64. –

+6

Ta odpowiedź została wymieniona w poście na blogu * [Wyrównanie danych dla prędkości: mit lub rzeczywistość?] (Http://lemire.me/blog/archives/2012/05/31/data-alignment-for-speed-myth- lub-reality /) *. –

6

To bardzo zależy od architektury układu. x86 i POWER są bardzo wyrozumiałe, Sparc, Itanium i VAX rzucają różne wyjątki.

+0

Bardzo dziękuję za odpowiedź – user172818

+7

w rzeczy samej zależy od procesora, ostatnio pracowałem nad procesorem DSP, który z przyjemnością będzie kontynuował używanie najbliżej wyrównanego adresu pamięci, gdy zostanie poproszony o operację na niezaanalizowanym. *, zburzyłeś niewymagającą pamięć dostęp do indywidualnego. –

+0

Rzeczywiście, po co zawracać sobie głowę nawet tymi ostatnimi bitami - Prawdziwi mężczyźni wiedzą, co robią, w każdym razie :) Z drugiej strony, byłoby wygodną architekturą używać oznaczonych wskaźników, jeśli używasz ignorowanych bitów dla tagu ... –

2

Rozważmy następujący przykład właśnie testowane na ARM9:

//Addresses  0  1  2 3  4  5  6  7  8 9 
U8 u8Temp[10] = {0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00}; 

U32 u32Var; 

u32Var = *((U32*)(u16Temp+1)); // Let's read four bytes starting from 0x22 

// You would expect that here u32Var will have a value of 0x55443322 (assuming we have little endian) 
// But in reallity u32Var will be 0x11443322! 
// This is because we are accessing address which %4 is not 0. 
+2

Myślę, że masz błąd ortograficzny - twoje trzecie zdanie odwołuje się do '' ' zmienna u16Temp', gdzie jest jej deklaracja? Widzę tylko "u8Temp". – amn

Powiązane problemy