Domande da un "manichino" - pagina 126

 
Renat:

Da quando tutti gli array sono statici, e anche tutte le dimensioni e gli indici sono statici?

Poiché gli array sono quasi sempre dinamici e gli indici sono variabili, non si possono fare seri controlli statici al momento di una chiamata. Gli unici controlli che rimangono da fare sono i controlli meta/rtti ed è per questo che è così importante avere accesso a tutto l'oggetto/descrizione e non lavorare al volo con un pezzo di memoria.

Quindi, andiamo con ordine. Per gli array statici, tutto è facile da controllare in fase di compilazione, giusto?

Per quelli dinamici (che hanno oggetti nascosti!), c'è una meta-informazione in runtime, giusto? C'è! Certo che c'è.

Tutto ciò che rimane è specificare i controlli di run-time nel codice eseguibile della funzione da compilare. E questo è tutto!

E non sto dicendo che sia una passeggiata. Beh, anche Slava (Stringo) sa il fatto suo. Chi ha vita facile al giorno d'oggi, comunque? :)

// Dopo tutto: si fa tutto in quattro.

// Se hanno già degli array dinamici, usate le meta-informazioni che portano con sé ovunque!

// Avendolo, si possono fare anche cose meravigliose (come permettere all'utente di passare array di dimensioni sconosciute).

// Ma in mql5(!), non si può nemmeno passare un array bidimensionale con entrambe le incognite in una funzione.

// Anche in rospo antico si può fare. :))

 
Renat:

Non preoccupatevi, tutto è stato pensato molto tempo fa.

Le conseguenze della rottura dei principi di protezione le conosciamo molto bene - è il modo "in aprile abbiamo risolto altri 12 bug critici che permettono di uscire dalla macchina virtuale e ottenere il controllo del sistema".

Le conseguenze di questa particolare soluzione non sanno nemmeno di "controllo del sistema". Il massimo che può fare è mandare in crash la memoria di "qualcun altro" se è fuori dal range dell'array controllato in modo errato.
 
MetaDriver:

1. Questo era il mio suggerimento per introdurre la denominazione e quindi la tipizzazione rigida, soprattutto perché è l'unico posto non coperto dalla tipizzazione di denominazione, quindi si adatta bene all'ideologia di universalizzazione delle entità del linguaggio.

2. Tutti uguali: in primo luogo, è storto, e in secondo luogo, non è affatto universale. Suggerisci un modo(1) per copiare un mql-array bidimensionale in un buffer OpenCL senza inutili riscritture e wrapping in strutture, o(2) usando (per la velocità) la tua funzione ArrayCopy(...) per array non uniformi.

// Scusate per la bruschezza del post precedente. Davvero inutile. Mi sono eccitato al "non complichiamo le cose". In quanto porta solo a complicazioni.

2a. Penso che il tuo "vincolo di monodimensionalità" per funzioni come ArrayCopy() possa essere attenuato in molti casi in modo indolore con una clausola elementare nei commenti: "La funzione funziona anche con gli array multidimensionali, purché l'array multidimensionale sia copiato nella sua interezza. "

Questo eliminerebbe molti problemi. // Ma non tutti, ovviamente.

Ci sono due modi, uno è quello di copiare gli array monodimensionali separatamente, ma questo non va bene, perché l'interfaccia OCL sarà ingombra di array,

Il secondo modo è quello di rappresentare un array unidimensionale come uno bidimensionale, perché sarà comunque passato a OCL per nastro. Quindi va così. A proposito, gli stessi spostamenti di dati quando si cambia la dimensione potrebbero essere fatti in OCL copiando una parte dell'array; tutto dipende dalla dimensione e se è conveniente.

class CArrayTwo_merniy
  {
   float             a[];
   int               size_i;
   int               size_j;
public:
                     CArrayTwo_merniy(void){size_i=0;size_j=0;};
                    ~CArrayTwo_merniy(void){};
   void              Resize(int i,int j)
     {
      int size;
      if(j<size_j)// если уменьшаем j размер массива
        {
         for(int l=1;l<i;l++)
            for(int k=0;k<j;k++)
               a[l*i+k]=a[l*size_i+k];
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {size_i=i; size_j=j;}
         return;
        }
      else // иначе, если увеличиваем j размер массива
        {
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {
            for(int l=i-1;l>=0;l--)
               for(int k=j-1;k>=0;k--)
                  a[l*i+k]=a[l*size_i+k];
            size_i=i; size_j=j;
           }
        }
     };
   void set(int i,int j,float v)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)a[i*size_i+j]=v;
      else Print("Ошибка set ["+i+":"+j+"]");
     };
   float get(int i,int j)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)return(a[i*size_i+j]);
      else {Print("Ошибка get ["+i+":"+j+"]"); return(EMPTY_VALUE);}
     };
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CArrayTwo_merniy ar; string t;
   ar.Resize(3,3); int cnt=0;
   for(int i=0;i<3;i++)for(int j=0;j<3;j++){ar.set(i,j,(float)cnt); cnt++;}
   t="исх ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(5,5);
   t="5х5 "; for(int i=0;i<5;i++){for(int j=0;j<5;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(3,3);
   t="3х3 ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
  }
 
Urain:

Ci sono due modi, uno è quello di copiare gli array monodimensionali separatamente, ma non va bene, perché l'interfaccia OCL sarà ingombra di array,

Il secondo modo è quello di rappresentare un array unidimensionale come uno bidimensionale, perché sarà comunque passato a OCL per nastro. Quindi va così. A proposito, gli stessi spostamenti di dati quando si cambia la dimensionalità possono essere fatti in OCL copiando una parte dell'array; tutto dipende dalla dimensione e da quanto è conveniente.

многа многа букаф

Ne ho abbastanza di tutto questo. :) Occam è isterico...

;)

Qui ho un array bidimensionale. Ho il suo sizeof(My2DArray). Di cos'altro ho bisogno per copiarlo nel buffer? Comunque, nessuno mi ha nemmeno fornito un offset nel mio array per renderlo una variabile. Quindi, no. Prima devo riscriverlo (il che porta a ritardi), o scrivere il mio array bidimensionale (!!) Oh, mio Dio. E a cosa serve? Per tenermi al sicuro. (!) Ecco, sto ridendo. :)))

 
MetaDriver:

Questo è tutto ciò di cui ho avuto abbastanza. :) Occam è isterico...

;)

:))

Francamente, l'overhead del ridimensionamento è enorme, ma è possibile ridurlo usando OCL per queste cose.

Ma la copia diretta di un array bidimensionale in un buffer OCL.

E non vi consiglierei di ripartire l'array ad ogni starnuto.

Così com'è, è abbastanza applicabile.

 
MetaDriver:

Questo è tutto ciò di cui ho avuto abbastanza. Occam è isterico...

;)

Dai, tre funzioni di set get e resize.

L'ho scritta per te sulle mie ginocchia, mentre tu hai fatto il broncio.

 
Urain:
Dai, sono un sacco di parole, tre funzioni set get e Resize
È forte, scommetto. Quando ci faranno sovraccaricare gli operatori (e non dimenticate di rendere sovraccaricabili gli operatori "[ ]" e "=", allora ci divertiremo. Saremo in grado di vendere i nostri array dinamici sul mercato. E lo prenderanno! E chi non li prenderà - spegniamo la trasmissione del gas degli array multidimensionali nelle funzioni. :)
 
MetaDriver:
Fico, senza dubbio. Quando ci faranno l'overloading degli operatori (e non dimenticate di rendere l'operatore "[ ]" precaricabile, allora sarete felici. Venderemo i nostri array dinamici sul mercato. E lo prenderanno! E chi non lo prenderà - spegniamo la trasmissione del gas degli array multidimensionali nelle funzioni. :)
Non lo dimenticheremo ;)
 
mql5:
Non lo dimenticheremo ;)
:))
 
MetaDriver:

Ho un array bidimensionale. Ho il suo sizeof(My2DArray). Di cos'altro ho bisogno per copiarlo nel buffer? Comunque, nessuno mi ha nemmeno fornito un offset nel mio array per renderlo una variabile. Quindi, no. Prima devo riscriverlo (il che porta a ritardi), o scrivere il mio array bidimensionale (!!) Beh, questo è un casino. E a cosa serve? Per tenermi al sicuro. (!) Ecco, sto ridendo. :)))

Caro signore, guardi il contesto.

1) Quando saltate da un ambiente controllato e sicuro a un buffer grezzo completamente incontrollato, siete voi che siete responsabili della compatibilità con quell'ambiente binario.

2) Quando si scrive codice, si è responsabili dell'architettura di quel codice. E non lamentatevi che "è difficile mettere un cavallo e una cerva nello stesso carro" quando usate strutture diverse.

3) Vi consiglio di leggere la descrizione di CLBufferRead e CLBufferWrite - grazie al riferimento universale void*, potete passare qualsiasi tipo di riferimento a OpenCL. E ci sono anche gli offset e le dimensioni.

uint  CLBufferRead(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из буфера для чтения, по умолчанию весь буфер
   );
uint  CLBufferWrite(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из массива для записи, по умолчанию весь массив
   );

Vedo che il soggetto è stato appena grattato via dal nulla.