Всегда ли невыровненный доступ к памяти вызывает ошибки шины?

В соответствии с ошибкой сегментации страницы в Википедии ошибка шины может быть вызвана неравномерным доступом к памяти. В статье приведен пример того, как вызвать ошибку шины. В этом примере мы должны включить проверку выравнивания, чтобы увидеть ошибку шины. Что если мы отключим такую ​​проверку выравнивания?

Программа, кажется, работает правильно. У меня часто есть доступ к невыровненной памяти программы, и она используется довольно многими людьми, но никто не сообщает мне об ошибках шины или других странных результатах. Если мы отключим проверку выравнивания, каков побочный эффект невыровненной памяти?

Платформы: я работаю на x86 / x86-64. Я также попробовал свою программу, скомпилировав ее с помощью "gcc -arch ppc" на Mac, и она работает правильно.

3 ответа

Решение
  1. Это может быть значительно медленнее для доступа к невыровненной памяти (как в несколько раз медленнее).

  2. Не все платформы поддерживают даже выравниваемый доступ - например, x86 и x64, но ia64 (Itanium) - нет.

  3. Компилятор может эмулировать доступ без выравнивания (VC++ делает это для указателей, объявленных как __unaligned на ia64, например) - путем вставки дополнительных проверок для обнаружения невыровненного регистра и загрузки / сохранения частей объекта, которые охватывают границу выравнивания по отдельности. Это даже медленнее, чем доступ без выравнивания на платформах, которые изначально поддерживают его.

Это очень сильно зависит от архитектуры чипа. x86 и POWER очень снисходительны, Sparc, Itanium и VAX создают разные исключения.

Рассмотрим следующий пример, который я только что протестировал на 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.
Другие вопросы по тегам