![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| null56 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
Всем привет
Процессор x86/x86_64 Задачи: 1) понять что такое проверка на выравненные данные 2) понять почему срабатывает проверка в конкретном примере 3) понять почему не срабатывает проверка в другом примере 4) понять зачем вообще эта проверка нужна? то есть был введен флаг в регистре СЛОВА (бит 18) http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%...%B3%D0%BE%D0%B2 И так Вопрос 1: правильно ли я понимаю понятие "проверка на выравнивание"? проверка на выравнивание - это ошибка в том случае, когда идет ДОСТУП к данным в оперативной памяти не по кратному машинному слову адресу (4 - для x86, 8 - для ) или это связано с размером данных и адресом? скажем, если читаем 2 байта, то адрес должен быть кратен 2м, 4 - 4м?
И так пример: компилятор gcc 64 разрядный, поэтому буду использовать опцию -m32, чтобы сделать тесты 32разрядных приложений Для незнающих gnu assembler: вставка 1) сохраняет в стек регистр слова, 2) изменяет в этом значении 18 бит, 3) загружает слово обратно в регистр. Код проверенных в дебагере, ошибок нет 32 бита: сборка с флагом -m32
Результат: "Ошибка шины" Вопрос 2: если я правильно понимаю понятие "проверка на выравнивание", то тогда не понимаю, почему в данном примере идет какая - то проверка? ведь я даже к памяти не обратился? 64 бита (в ассемблерной вставке используется расширенный регистр указателя стека rsp, а так та же суть)
Результат: ошибка добиться не получилось Вопрос 3: как добиться аналогичной x86 ошибки на 64 битах? ну и на конец Вопрос 4: для чего нужна эта проверка? в соседних темах были разговоры о более быстром доступе, размещение в кеше еще чего - то... Но, вопрос именно ЗАЧЕМ нужна проверка? где ее можно использовать? Спасибо всем отклинувшимся за помощь Это сообщение отредактировал(а) null56 - 27.3.2014, 13:15 |
||||||
|
|||||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
вопрос 1, наверное можно снять, нашел правила выравнивания тут
http://www.intel.com/content/www/us/en/arc...t-1-manual.html иными словами, правильнее будет считать, что начальный адрес должен быть кратен размеру данных Это сообщение отредактировал(а) null56 - 27.3.2014, 13:32 |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Некоторые процессоры просто требуют выровненного доступа. Т.е. если ты пытаешься прочитать 4 байта по адресу не кратному 4, то: 1. возникнет аппаратное исключение 2. будет прочитано хрен знает что (скорее всего, будет прочитано 4 байта с адреса address & ~(4 - 1)) Чтобы это не происходило компилятор выравнивает весь доступ. Если это невозможно, то читает по 1 байту. И вместо одной инструкции для чтения 32-х битного слова ты получаешь минимум 4 штуки. |
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
bsa, да про исключение я знаю, у нас на blackfin как раз падает всё
тут ключевое слово "некоторые процессоры". так вот вопрос: зачем на процах(такие как x86), которые умеют читать по невыровненным адресам, этот флажок? для отладки? чтобы переносить на другие процы что ли? |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Производительность разная. Данные выровненные на границу 4/8ми байт быстрее адресуются, чем выравненные на границу 1го байта. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
null56, посмотри первую часть статьи
|
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 2 Всего: 12 |
vinter, спасибо за статью, очень наглядно, хотя урывки я вроде где - то уже читал, вроде бы в мейерсе, про тривиальные классы
Alexeis, vinter, а теперь прочитаем внимательнее вопрос... может я его не верно задал?
вы мне сказали верно, "выравнивание - это ... и она для того - то..." но! вопрос связан с назначением 18 бита в слове процессора? по умолчанию он выключен на х86, если включаю, то включается и проверка.... вопрос: зачем надо включать этот флаг??? зачем он вообще присутствует в процессоре данной архитектуры? |
|||
|
||||
| k0rvin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Т.е. работа с массивом char менее эффективна, чем с массивом int? -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
нельзя этого утверждать, как нельзя утверждать и обратное. Всё нужно измерять. Это сообщение отредактировал(а) vinter - 4.4.2014, 15:29 |
|||
|
||||
| k0rvin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Ладно, фиг с ней, с эффективностью. Есть такой код:
Один знакомый сказал, что такой способ представления массива «опасен при кроссплатформенности — у разных аппаратных платформ разные требования к выравниванию. Необходимо принять меры в виде пустого куска между указателями и данными», но безопасного варианта он пока не предоставил. Может вы что подскажете? -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
k0rvin, да, твой способ хранения явно не лучший, в плане выравнивания. Во первых тебе нужно выделять память выровненную по Size. Потом тебе уже надо ручками подсчитать, где после Size должны располагаться Value* и это будет зависеть от размера указателя на платформе. Псле чего тебе нужно посчитать, опять руками, где можно начать располагать Value. На мой взгляд оно того не стоит
Это сообщение отредактировал(а) vinter - 5.4.2014, 08:50 |
|||
|
||||
| Alexeis |
|
||||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Достаточно посмотреть ассемблерный код. Но на самом деле речь об ином. Когда компилятор вставляет код записи в не выровненные поля то добавляются лишние инструкции. Массив байтов считается выравненным. Даже если поставить режим выравнивания на 8 или 16 байтов, все равно в массиве байты будут идти один за другим. Но тем не менее код записи в char длиннее чем в int размера в регистр. Могу предположить, что флаг связан с риск архитектурой
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||
|
|||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
нет не достаточно. Ты измерял выровненный и не выровненный код? Я вот измерял и мне пришлось изрядно потрудиться, чтобы написать код при котором будет хотя бы 5% разница на моём core i7. x86 не является RISC, а то, что там внутри наружу выдавать никто не будет, на мой взгляд |
|||
|
||||
| k0rvin |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Зачем?
А «2*sizeof(Size)» по-твоему зачем? Впрочем тут все относительно просто, как мне предложили
Но размер массива m не известен в compile-time, поэтому я не могу узнать, сколько он на самом деле займет памяти с учетом выравнивания.
«m*sizeof(Value *)» чем не устраивает? Т.е. собвственно проблема в том, чтобы узнать, какое выравнивание использует текущая среда (компилятор+ОС+железо). -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
||||||
|
|||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
затем, что если ты задумался о выравнивании, то нужно чтобы первый объект твоих данных находился по выровненному адресу. В твоём коде этого нет. понятия не имею, но к выравниванию это не имеет никакого отношения. К примеру, Size Равный 5 байт. 2*5 = 10. mallco выделяет память по адресу 3. Значит первый Size находится по адресу 3, второй по адресу 8. Указатель по адресу 13. В результате мы имеем чёрти-что. Понятно? тоже самое. так просто или непонятно как сделать?
я понимаю твою запись как: выделить память под 2 Size, m указателей на Value и m x n объектов типа Value. Если всё так, то я не вижу просто го способа решения этой проблемы - нужно много считать и не ошибиться при этом |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |