Errori, bug, domande - pagina 1952

 
Stanislav Korotky:

Il compilatore non aiuta qui - testato - l'oggetto locale di ritorno viene duplicato e poi inchiodato. Non esiste una mossa ottimale in questo caso.


Avete fatto dei test di velocità? O solo la diagnosi della creazione dell'oggetto? Se è il secondo, allora naturalmente non verrà rimosso nulla dal codice, perché voi stessi lo impedite con i vostri controlli.

 
Alexey Navoykov:


Avete fatto dei test di velocità? O stai solo diagnosticando il fatto della creazione dell'oggetto? Se è la seconda, ovviamente non verrà tagliato nulla dal codice, dato che voi stessi lo impedite attraverso i vostri controlli.

Com'è? Tutti i miei controlli consistono solo in tracce impostate nei costruttori e nei distruttori. Se le copie extra vengono create e cancellate, è una prova sufficiente per me che non c'è ottimizzazione.

 
Alexey Navoykov:


Avete fatto dei test di misurazione della velocità? O solo diagnosticare il fatto della creazione dell'oggetto? Se la seconda, allora naturalmente non verrà tagliato nulla dal codice, perché voi stessi lo impedite con i vostri controlli.

Beh, se non si possono muovere linee, non si possono muovere oggetti più complessi.

 
Stanislav Korotky:

Com'è? Tutti i miei controlli consistono solo in tracce impostate nei costruttori e nei distruttori. Se vengono create e cancellate copie extra, questo per me è una prova sufficiente della mancanza di ottimizzazione.

L'ottimizzatore non può strappare un frammento contenente la vostra traccia). Solo le cose che non influenzano la tua logica possono essere tagliate.
 

Ora in OnTesterInit è possibile impostare intervalli di ottimizzazione per ogni parametro di input. Il tester genera quindi una tabella di passaggio da solo, la divide nel numero di Agenti/Pacchetti e la invia agli Agenti. Questa tabella non è modificabile in alcun modo ora.

Ma durante l'ottimizzazione è in realtà molto comune preoccuparsi prima di tutto dei passaggi dove cambia qualche parametro importante, poi dove ne cambia un altro, ecc. Se fosse possibile modificare una tabella generata di passaggi (per cambiare i posti degli elementi (insiemi di parametri di input)) o generarla da soli, sarebbe possibile impostare la priorità necessaria, quando i passaggi più interessanti andrebbero agli agenti per primi, e poi - i passaggi meno interessanti.


Perciò propongo di aggiungere a OnTesterInit la possibilità di cambiare la tabella dei passaggi formata di default:

long PassesTotal(); // количество проходов в таблице для Оптимизации

// Получает список входных параметров соответствующего прохода
int PassesGet( const int Index,  MqlParam& Parameters[] );


// Прописывает список входных параметров для соответствующего прохода,
// если индекс не меньше размера таблицы, то идет дозапись в конец таблицы и размер ее увеличивается на единицу
int PassesSet( const int Index, const MqlParam& Parameters[] );
 
Alexey Navoykov:
L'ottimizzatore non sarà in grado di tagliare la sezione che contiene la vostra traccia.) L'unica cosa che può essere tagliata è quella che non interferisce con la vostra logica.

Bene, l'argomento è finito ;-). Penso che l'ottimizzazione in questo caso potrebbe avvenire solo in quel punto del codice in cui si verifica il valore di ritorno, e non dipende in alcun modo da ciò che è scritto nel costruttore.

Standard C++11: quando certi criteri sono soddisfatti, un'implementazione è autorizzata a omettere la costruzione di copia/spostamento di un oggetto di classe, anche se il costruttore di copia/spostamento e/o il distruttore dell'oggetto hanno effetti collaterali. In questi casi, l'implementazione tratta l'origine e la destinazione dell'operazione di copia/spostamento omessa come semplicemente due modi diversi di riferirsi allo stesso oggetto, e la distruzione di quell'oggetto avviene nell'ultimo dei momenti in cui i due oggetti sarebbero stati distrutti senza l'ottimizzazione.

 
Stanislav Korotky:

Bene, l'argomento è finito ;-). Secondo me, l'ottimizzazione in questo caso potrebbe avvenire solo in quel luogo del codice dove avviene il ritorno del valore, e non dipende in alcun modo da ciò che è scritto nel costruttore.

Comunque, mi dispiace dire che il compilatore MQL è lontano dall'essere così intelligente come pensavo che fosse ) Ho provato a fare alcuni semplici esempi e ho scoperto che anche se creo un oggetto fittizio, che non viene usato da nessuna parte e non fa nulla, il compilatore non se ne preoccupa. Non è ottimizzato per niente. Sto giudicando solo dalla velocità. E per qualche motivo funziona più lentamente nelle nuove build che in quelle vecchie.

Ecco un codice banale:

class A { };

void OnStart()
  {
    uint starttick= GetTickCount();
    for (int i=0; i<1 e8; i++)
    { 
      A a;
    }
    Print(GetTickCount()-starttick," ms");
  }
 
Alexey Navoykov:

Beh, devo purtroppo ammettere che il compilatore MQL non è così intelligente, come pensavo che fosse ) Direi addirittura che non è per niente intelligente).


Hai mai pensato che potrebbe essere sintonizzato per ottimizzare le cose reali che la maggior parte della gente usa, piuttosto che le sciocchezze che hai appena inventato dal nulla?

 
Stanislav Korotky:

Bene, l'argomento è finito ;-). Secondo me, l'ottimizzazione in questo caso potrebbe avvenire solo in quel luogo del codice dove avviene il ritorno del valore, e non dipende in alcun modo da ciò che è scritto nel costruttore.


È solo in 2 anni che sono stati introdotti i costruttori di copie.
RVO (return value optimization) e NRVO (named return value optimization) sono i prossimi...

 
Sergey Dzyublik:

Avete considerato che potrebbe essere affilato per ottimizzare le cose reali che la maggior parte della gente usa, piuttosto che le stronzate che stanno inventando dal nulla?

Cos'è "la vera roba che la maggior parte della gente usa"?