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

 
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:

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

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

 
fxsaber:

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

Не помните где об этом писали?

 
fxsaber:

Тогда боюсь, смысл выравнивания теряется

попробовал в байтах посмотреть что выравнивание делает:

#property strict

const uint FFFF=0xFFFFFFFF;
//+------------------------------------------------------------------+
struct A pack(4)
  {
   ushort            j;
  };
//+------------------------------------------------------------------+
struct B pack(8)
  {
   ushort            j;
  };
//+------------------------------------------------------------------+
union UnionCheckByte
  {
   uint              byte_2x4[2];
   A                 a;
   B                 b;
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   UnionCheckByte tst;
   tst.byte_2x4[0]=FFFF;   tst.byte_2x4[1]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   Print("0xFFFFFFFF FFFFFFFF = ",tst.byte_2x4[0],",",tst.byte_2x4[1]);   // проверим
   
   
   
   tst.byte_2x4[0]=FFFF;   tst.byte_2x4[1]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   tst.a.j=0;
   Print("A.  = ",tst.byte_2x4[0],",",tst.byte_2x4[1]);   // проверим



   tst.byte_2x4[0]=FFFF;   tst.byte_2x4[1]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   tst.b.j=0;
   Print("B.  = ",tst.byte_2x4[0],",",tst.byte_2x4[1]);   // проверим
  }
//+------------------------------------------------------------------+

2019.07.07 17:51:30.601 tst (EURUSD,H1) 0xFFFFFFFF FFFFFFFF = 4294967295,4294967295

2019.07.07 17:51:30.601 tst (EURUSD,H1) A.  = 4294901760,4294967295

2019.07.07 17:51:30.601 tst (EURUSD,H1) B.  = 4294901760,4294967295




или я еще не проснулся, или не работает выравнивание pack(4) / pack(8) , я компилятору однозначно указал размеры структур A и B


даже так:

 ZeroMemory(tst.a);   //tst.a.j=0;
ничего не изменилось
 
Alexey Viktorov:

Не помните где об этом писали?

Не помню, в документации об этом есть.

 
Igor Makanu:

попробовал в байтах посмотреть что выравнивание делает:

или я еще не проснулся, или не работает выравнивание pack(4) / pack(8) , я компилятору однозначно указал размеры структур A и B

Так с этого и началось данное обсуждение. Оказалось, что все совсем не так.

Ну и пример некорректный все таки. Обнуляя ushort-поле, добавочные байты вовсе не обязаны меняться.


ZeroMemory, скорее всего, ориентируется на sizeof, а он двойка в обоих случаях по каким-то своих причинам.

 
fxsaber:

Так с этого и началось данное обсуждение. Оказалось, что все совсем не так.

1. Ну и пример некорректный все таки. Обнуляя ushort-поле, добавочные байты вовсе не обязаны меняться.


2 ZeroMemory, скорее всего, ориентируется на sizeof, а он двойка в обоих случаях по каким-то своих причинам.


1. да согласен

2. ZeroMemory как раз и должен мне обнулить память


в общем не вижу я смысла в pack() в чистом MQL, максимум можно в .dll погонять данные, но уж там то точно должно работать - так разработчики заявили

 
Igor Makanu:

2. ZeroMemory как раз и должен мне обнулить память

Так и происходит

struct A pack(4)
{
  short j;
  char i;
};

union U
{
  A a;
  uchar Bytes[sizeof(A)];
  
  U() { ArrayInitialize(this.Bytes, (char)0xFF); }
};

void OnStart()
{
  U u;
  
  ArrayPrint(u.Bytes); // 255 255 255 255
  
  ZeroMemory(u.a);
  ArrayPrint(u.Bytes); // 0 0 0 0
}