Ошибки, баги, вопросы - страница 2499

 
fxsaber:

Поэтому и возникает вопрос, как на самом деле работает выравнивание? Документация и Хабр своими примерами не раскрыли алгоритм.

от конкретного компилятора все зависит, наверное можно в MQL попробовать в union посмотреть как данные были сохранены при использовании  pack(4)

 
Igor Makanu:

от конкретного компилятора все зависит, наверное можно в MQL попробовать в union посмотреть как данные были сохранены при использовании  pack(4)

Для этого есть offsetof и другие способы.


ЗЫ Получается, что задание выравнивания служит для придания однозначности. Но не для собственного использования. Ну и хорошо видно, что от порядка полей зависит потребление памяти и, видимо, производительность.

 
fxsaber:

ЗЫ Получается, что задание выравнивания служит для придания однозначности. Но не для собственного использования.

а это и есть "от конкретного компилятора все зависит" - разработчики часто идут на ухищрения для поднятия производительности своих разработок относительно других, в MQL отсутствуют директивы компилятора - типа отключить оптимизацию исходного кода и т.п. - нельзя увидеть разницу в работе или использовании ОЗУ нативного  кода


ЗЫ: я не уверен, что пример с записью в файл однозначно всегда корректно работает, кто то недавно писал, что MQL используется Win API при записи в файл, тут может быть для совместимости с API функциями некоторые допущения быть произведены - но это мои догадки, не являюсь разработчиком компиляторов (((

[Удален]  
fxsaber:

Для этого есть offsetof и другие способы.


ЗЫ Получается, что задание выравнивания служит для придания однозначности. Но не для собственного использования. Ну и хорошо видно, что от порядка полей зависит потребление памяти.

Вы куда-то не туда копаете, выравнивание вообще не для вас нужно, это нужно процессору, чтобы не попал какой-нибудь int на две кеш-линии. То место, в которое будет производиться добивка - не регламентировано и зависит от компилятора, поэтому при передаче во внешний мир нельзя полагаться на pack(), только ручная добивка.

 
Vict:

Вы куда-то не туда копаете, выравнивание вообще не для вас нужно, это нужно процессору, чтобы не попал какой-нибудь int на две кеш-линии. То место, в которое будет производиться добивка - не регламентировано и зависит от компилятора, поэтому при передаче во внешний мир нельзя полагаться на pack(), только ручная добивка.

Стало ясно, всем спасибо.

 
fxsaber:

Хочется разобраться.

А что тут разбираться если в документации чётко написано

Имя структуры нельзя использовать в качестве идентификатора (имени переменной или функции). Следует иметь ввиду, что в MQL5 элементы структуры следуют непосредственно друг за другом без выравнивания. В языке C++ такое указание делается компилятору с помощью инструкции

#pragma pack(1)

И дальше по тексту...

То-есть выравнивание в MQL5 отсутствует вообще.

Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
  • www.mql5.com
Структура является набором элементов произвольного типа (кроме типа void). Таким образом, структура объединяет логически связанные данные разных типов. Объявление структуры Имя структуры нельзя использовать в качестве идентификатора (имени переменной или функции). Следует иметь ввиду, что в MQL5 элементы структуры следуют непосредственно друг...
 
Vict:

Вы куда-то не туда копаете, выравнивание вообще не для вас нужно, это нужно процессору, чтобы не попал какой-нибудь int на две кеш-линии. 

нет, кэш процессора вообще загружается с предвыборкой данных, причем различные уровни кэша вообще с предсказаниями переходов загружаются, туда (в кэш) вообще  pack() не может попасть, любая арифметическая операция (сложение 2-х int) вместо того чтобы выполниться на 1 или 3-х (гипотетических) тактах приведет к анализу выравнивания данных и т.п.

На физическом уровне это должно так работать: компилятор создал исполняемый код в нем да будут   pack(), но при загрузке данных из ОЗУ будет произведено только чтение int данных и указатель сегмента данных сразу будет перемещен на  pack() байт (не на int байт)


хотя могу сильно ошибаться, сейчас все процессы (включая работу самого процессора) виртуализированы и оптимизированы, так рассуждаю ибо книгу про Пентиум -1 читал когда учился.... жуть какая дорогая была в свое время ))))

[Удален]  
Igor Makanu:

нет, кэш процессора вообще загружается с предвыборкой данных, причем различные уровни кэша вообще с предсказаниями переходов загружаются, туда (в кэш) вообще  pack() не может попасть, любая арифметическая операция (сложение 2-х int) вместо того чтобы выполниться на 1 или 3-х (гипотетических) тактах приведет к анализу выравнивания данных и т.п.

На физическом уровне это должно так работать: компилятор создал исполняемый код в нем да будут   pack(), но при загрузке данных из ОЗУ будет произведено только чтение int данных и указатель сегмента данных сразу будет перемещен на  pack() байт (не на int байт)

Ну я не говорил, что спецификатор pack() служебная инфа для ЦПУ, имелось в виду - все эти пляски с выравниванием в интересах ЦПУ, а не программиста. Естественно, что реализуется компилятором посредством вставки пустоты в структуры.

 
Alexey Viktorov:

То-есть выравнивание в MQL5 отсутствует вообще.

Давно, как присутствует.

[Удален]  
Vict:

Вы куда-то не туда копаете, выравнивание вообще не для вас нужно

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