Erreurs, bugs, questions - page 1952

 
Alexey Navoykov:


Avez-vous effectué des tests de vitesse ? Ou êtes-vous en train de diagnostiquer le fait de la création d'un objet? Dans ce dernier cas, rien ne sera bien sûr supprimé du code puisque vous l'avez vous-même empêché par vos contrôles.

Comment ça ? Toutes mes vérifications consistent uniquement en des traces établies dans les constructeurs et les destructeurs. Si des copies supplémentaires sont créées et supprimées, c'est une preuve suffisante pour moi qu'il n'y a pas d'optimisation.

 
Alexey Navoykov:


Avez-vous effectué des tests de mesure de la vitesse ? Ou simplement le diagnostic du fait de la création de l'objet? Si c'est la seconde, rien ne sera bien sûr coupé du code, car vous l'empêchez vous-même avec vos contrôles.

Si on ne peut pas déplacer des lignes, on ne peut pas déplacer des objets plus complexes.

 
Stanislav Korotky:

Comment ça ? Toutes mes vérifications consistent uniquement en des traces établies dans les constructeurs et les destructeurs. Si des copies supplémentaires sont créées et supprimées, cela constitue pour moi une preuve suffisante de l'absence d'optimisation.

L'optimiseur ne peut pas arracher un fragment contenant votre trace). Seuls les éléments qui n'affectent pas votre logique peuvent être coupés.
 

Désormais, dans OnTesterInit, vous pouvez définir des plages d'optimisation pour chaque paramètre d'entrée. Le testeur génère ensuite lui-même une table de passage, la divise en fonction du nombre d'agents/de paquets et l'envoie aux agents. Ce tableau n'est plus modifiable d'aucune façon.

Mais pendant l'optimisation, il est en fait très courant de se préoccuper d'abord des passages où un paramètre important change, puis où un autre change, etc. S'il était possible d'éditer un tableau de passages généré (pour changer la place des éléments (ensembles de paramètres d'entrée)) ou de le générer soi-même, il serait possible de définir la priorité nécessaire, lorsque les passages les plus intéressants vont d'abord aux agents, et ensuite - les passages moins intéressants.


C'est pourquoi je propose d'ajouter à OnTesterInit la possibilité de changer la table des passes par défaut :

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

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


// Прописывает список входных параметров для соответствующего прохода,
// если индекс не меньше размера таблицы, то идет дозапись в конец таблицы и размер ее увеличивается на единицу
int PassesSet( const int Index, const MqlParam& Parameters[] );
 
Alexey Navoykov:
L'optimiseur ne sera pas en mesure de couper la section contenant votre trace). La seule chose qui peut être supprimée est celle qui n'interfère pas avec votre logique.

Eh bien, le sujet est clos ;-). Je pense que l'optimisation dans ce cas ne peut se faire qu'à l'endroit du code où la valeur de retour apparaît, et ne dépend en aucun cas de ce qui est écrit dans le constructeur.

Norme C++11: Lorsque certains critères sont remplis, une implémentation est autorisée à omettre la construction de la copie/déplacement d'un objet de classe, même si le constructeur et/ou le destructeur de la copie/déplacement de l'objet ont des effets secondaires. Dans ce cas, l'implémentation traite la source et la cible de l'opération de copie/déplacement omise comme deux façons différentes de se référer au même objet, et la destruction de cet objet se produit au dernier moment où les deux objets auraient été détruits sans l'optimisation.

 
Stanislav Korotky:

Eh bien, le sujet est clos ;-). À mon avis, l'optimisation dans ce cas ne pourrait avoir lieu qu'à l'endroit du code où le retour de la valeur a lieu, et elle ne dépend en aucun cas de ce qui est écrit dans le constructeur.

Quoi qu'il en soit, je dois admettre à regret que le compilateur MQL est loin d'être aussi intelligent que je le croyais...) Je dirais même qu'il n'est pas intelligent du tout. ) J'ai essayé de faire quelques exemples simples et il s'est avéré que même si je crée un objet factice, qui n'est utilisé nulle part et ne fait rien, le compilateur ne s'en soucie pas. Ce n'est pas du tout optimisé. Je ne juge que par la vitesse. Et pour une raison quelconque, il fonctionne plus lentement dans les nouvelles constructions que dans les anciennes.

Voici un code trivial :

class A { };

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

Eh bien, je dois malheureusement admettre que le compilateur MQL n'est pas aussi intelligent que je le pensais). Je dirais même que ce n'est pas du tout intelligent).


Avez-vous déjà pensé qu'il pourrait être réglé pour optimiser les choses réelles que la plupart des gens utilisent, plutôt que les absurdités que vous avez inventées de toutes pièces ?

 
Stanislav Korotky:

Eh bien, le sujet est clos ;-). A mon avis, l'optimisation dans ce cas ne pourrait avoir lieu qu'à l'endroit du code où le retour de valeur a lieu, et ne dépend en aucun cas de ce qui est écrit dans le constructeur.


Ce n'est que depuis deux ans que les constructeurs de copies ont été introduits.
RVO (return value optimization) et NRVO (named return value optimization) sont les prochaines étapes...

 
Sergey Dzyublik:

Avez-vous pensé qu'il pourrait être affiné pour optimiser les choses réelles que la plupart des gens utilisent, plutôt que les conneries qu'ils fabriquent de toutes pièces ?

qu'est-ce que "le vrai truc que la plupart des gens utilisent" ?
 
Alexey Navoykov:

En général, j'admets à regret que le compilateur MQL n'est pas aussi intelligent que je le pensais). Je dirais même qu'il n'est pas intelligent du tout. ) J'ai essayé de faire quelques exemples simples et il s'est avéré que même si je crée un objet factice, qui n'est utilisé nulle part et ne fait rien, le compilateur ne s'en soucie pas. Ce n'est pas du tout optimisé. Je ne juge que par la vitesse. Et pour une raison quelconque, il fonctionne plus lentement dans les nouvelles constructions que dans les anciennes.

Les développeurs en sont conscients. Mais une telle optimisation par le compilateur est loin d'être la priorité des tâches à résoudre.

Il y a aussi de telles ambiguïtés du compilateur.

Raison: