Errori, bug, domande - pagina 2500

 
Vict:

Stai scavando in un posto sbagliato. Non hai affatto bisogno dell'allineamento, il processore ne ha bisogno per non avere qualche int su due linee di cache.

no, la cache del processore è caricata con il prefetching dei dati a tutti, e diversi livelli di cache sono caricati con previsioni di transizione a tutti, pack() non può arrivare (nella cache) a tutti, qualsiasioperazione aritmetica (aggiunta di 2 int) invece di essere eseguita su 1 o 3 (ipotetici) cicli di clock risulterà in analisi di allineamento dei dati, ecc.

A livello fisico dovrebbe funzionare così: il compilatore ha creato codice eseguibile in esso sì, ci saràpack(), ma quando si caricano dati dalla RAM leggerà solo dati int e il puntatore al segmento dati sarà immediatamente spostato apack() byte (non int byte)


anche se potrei sbagliarmi, ora tutti i processi (compreso il processore stesso) sono virtualizzati e ottimizzati - questo è il mio ragionamento, dato che ho letto il libro sul Pentium-1 quando ho studiato -.... era così costoso ai tempi ))))

 
Igor Makanu:

no, la cache del processore è caricata con il prefetching dei dati a tutti, e diversi livelli di cache sono caricati con previsioni di transizione a tutti, pack() non può arrivare (nella cache) a tutti, qualsiasi operazione aritmetica (aggiunta di 2 int) invece di essere eseguita su 1 o 3 (ipotetici) cicli di clock risulterà in analisi di allineamento dei dati, ecc.

A livello fisico dovrebbe funzionare così: il compilatore ha creato un codice eseguibile in esso sì, ci saràpack(), ma quando carica i dati dalla RAM leggerà solo dati int e il puntatore al segmento dati sarà immediatamente spostato albyte pack() (non al byte int)

Beh, non ho detto che lo specificatore pack() è un'informazione di servizio per la CPU. Quello che volevo dire è che tutto questo ballare con l'allineamento nell'interesse della CPU e non del programmatore. Naturalmente, è implementato dal compilatore attraverso l'inserimento di uno spazio vuoto nelle strutture.

 
Alexey Viktorov:

Cioè, non c'è alcun allineamento in MQL5.

È stato presente per molto tempo.

 
Vict:

State scavando nel posto sbagliato, l'allineamento non fa per voi

Beh, anche se un uso reale che posso pensare è in un ambiente multithreaded, per organizzare i dati in modo che diversi core non scrivano sulla stessa linea di cache, questo può davvero rallentare le prestazioni a causa della costante sincronizzazione della cache. Beh, anche lì ci sono molte sfumature, come il tipo di CPU.

 
fxsaber:

È stato presente per molto tempo.

Si ricorda dove è stato scritto?

 
fxsaber:

Allora temo che si perda il punto di allineamento

provato in byte per vedere cosa fa l'allineamento:

#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) 0xFFFFFFFFFFFF FFFFFFFFFFFF = 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




O non mi sono ancora svegliato, o l'allineamento pack(4) / pack(8) non funziona, ho specificato esplicitamente le dimensioni delle strutture A e B al compilatore


anche così:

 ZeroMemory(tst.a);   //tst.a.j=0;
non è cambiato nulla
 
Alexey Viktorov:

Si ricorda dove è stato scritto?

Non ricordo se è nella documentazione.

 
Igor Makanu:

provato a vedere cosa fa l'allineamento in byte:

o non mi sono ancora svegliato, o l'allineamento pack(4) / pack(8) non funziona, ho detto senza ambiguità al compilatore le dimensioni delle strutture A e B

È così che è iniziata questa discussione. Si è scoperto che non è così.

Beh, questo campione non è corretto, dopo tutto. Quando si azzera il campo ushort, i byte aggiuntivi non devono cambiare affatto.


ZeroMemory è molto probabilmente guidato da sizeof mentre è due in entrambi i casi per qualche ragione propria.

 
fxsaber:

Ecco come è iniziata questa discussione. Si scopre che non è affatto così.

1. Beh, questo esempio non è corretto, dopo tutto. Azzerando il campo ushort, i byte aggiuntivi non devono essere cambiati affatto.


2. ZeroMemory deve essere guidato da sizeof mentre è doppio in entrambi i casi per qualche motivo.


1. sì, sono d'accordo

2. ZeroMemory dovrebbe semplicemente azzerare la memoria per me


Non vedo alcun senso in pack() in MQL puro, al massimo si può usare .dll per manipolare i dati, ma dovrebbe funzionare di sicuro - questo è ciò che hanno detto gli sviluppatori

 
Igor Makanu:

2. ZeroMemory è esattamente ciò di cui ho bisogno per resettare la memoria

Lo fa.

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
}