Erreurs, bugs, questions - page 2284

 
Slava:

Si c'est par des tics réels, oui.

Vous pouvez voir les statistiques sur la quantité de mémoire dépensée pour stocker les ticks en une seule passe. Lorsqu'il est optimisé, pas plus de 320 méga sont stockés en mémoire à la fois. Tout le reste est sur le disque.

Nous envisageons maintenant une solution pour conserver tous les ticks dans une mémoire partagée afin que tous les agents locaux puissent lire dans cette mémoire. Il n'y aura alors aucun accès au disque et l'optimisation sera plus rapide.

Oui, c'est de l'archivage. Si je comprends bien, maintenant les ticks et les barres de minutes sont stockés non emballés sur le disque et dans la mémoire, c'est à dire pour la barre(structure MqlRates) c'est 60 octets, et pour le tick(structure MqlTick) c'est 52 octets.
C'est horrible ! Il y a longtemps que quelque chose doit être fait à ce sujet.

Je comprends que le principal problème des tableaux compressés est d'organiser un accès rapide à chaque élément du tableau.

Mais même si nous ne conservons le déballage que pour chaque 256ème élément du tableau, et que nous ne stockons dans les autres éléments que les incréments des éléments déballés, nous pouvons constater que la taille du tableau sera réduite de 4 à 5 fois et que le temps d'accès à chaque élément n'augmentera pas beaucoup (peut-être 1 à 2 nanosecondes), mais nous gagnerons un temps énorme sur la sauvegarde et la lecture du tableau depuis le disque et vers le disque.

 
fxsaber:
Pourquoi le SSD est-il constamment adressé (le voyant clignote à un rythme élevé) pendant l'optimisation ?

C'est pourquoi je n'utilise pas de ticks, mais une structure de données logarithmique (dont j'ai déjà parlé) qui, à un moment donné, se compose de quelques milliers de ticks, puis de quelques milliers de barres de minutes, 2000 M2, 2000 M5 , M10, M30, H1, H3, H6, H12, D1, W1... tous les bars MN1.
Cette structure de données historiques complètes est formée à tout moment à moins d'une milliseconde et n'occupe que 1,5 Mo de RAM (en fait, même pas en RAM, mais dans le cache du processeur). Et tous les algorithmes, mis au point pour cette structure, s'envolent.

Après tout, notre vue est construite sur la même échelle logarithmique : plus on regarde loin, moins on remarque les petits détails.

Lorsque, dans un avenir pas trop lointain, les ordinateurs n'auront plus qu'un seul dispositif de mémoire physique (disque dur, RAM, cache du processeur), à savoir le cache du processeur avec 13 zéros dedans, alors je passerai moi aussi aux ticks :))

...

Quoique, peut-être que c'est moi qui suis à l'écart, car avec une telle structure de données, pendant l'optimisation, l'ampoule va aussi vaciller. Après tout, les tics seront toujours chargés :(((

 
Slava:

Si c'est par des tics réels, oui.

Vous pouvez voir les statistiques sur la quantité de mémoire dépensée pour stocker les ticks en une seule passe. Lorsqu'il est optimisé, pas plus de 320 méga sont stockés en mémoire à la fois. Tout le reste est sur le disque.

Nous envisageons maintenant une solution pour conserver tous les ticks dans la mémoire partagée, afin que tous les agents locaux puissent lire dans cette mémoire. Il n'y aura alors aucun accès au disque, et l'optimisation sera plus rapide.

Tout d'abord, commençons par le journal d'optimisation.

Tester  optimization finished, total passes 714240
Statistics      optimization done in 7 hours 31 minutes 06 seconds
Statistics      local 714240 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)
Core 1  connection closed
Core 2  connection closed
Core 3  connection closed
Core 4  connection closed
Core 5  connection closed
Core 6  connection closed
Core 7  connection closed
Core 8  connection closed
Tester  714240 new records saved to cache file 'tester\cache\Test.FILTER_EURUSD.rann_RannForex.M1.20180226.20180909.40.2D734373DF0CAD251E2BD6535A4C6C84.opt'

Pendant ces 7,5 heures, le SSD a été abordé avec une fréquence énorme. Si les tics ont été lus à chaque passage, cela revient à une moyenne de 26 fois par seconde pendant 7,5 heures. D'où un clignement d'œil aussi sauvage - plus de 700 000 lectures.


Journal d'une seule exécution

Core 1  FILTER_EURUSD.rann_RannForex,M1: 132843 ticks, 60283 bars generated. Environment synchronized in 0:00:00.140. Test passed in 0:00:00.827 (including ticks preprocessing 0:00:00.109).
Core 1  FILTER_EURUSD.rann_RannForex,M1: total time from login to stop testing 0:00:00.967 (including 0:00:00.140 for history data synchronization)
Core 1  322 Mb memory used including 36 Mb of history data, 64 Mb of tick data

Comme on le voit, ~130K ticks et 60K barres sont utilisés (le mode "Historique complet" est sélectionné dans le Testeur). C'est-à-dire une très petite quantité d'histoire.

L'historique des symboles personnalisés dans le terminal contient la quantité suivante de données historiques

Saved ticks = 133331
Generated Rates = 60609

C'est-à-dire que dans l'histoire du symbole est très peu plus que utilisé par le Testeur.


ZS C'est dommage de regarder la DSS... Combien plus rapide pourrait être l'Optimize ? Il est étrange que le système d'exploitation ne mette pas ces données en cache, puisqu'il s'agit de moins de 7 Mo de ticks sous forme non compressée.

 
Nikolai Semko:

Mais même si nous ne stockons que chaque 256ème élément d'un tableau non emballé et que nous ne stockons que les incréments des éléments non emballés, la taille d'un tableau sera réduite de 4 à 5 fois tandis que le temps d'accès à chaque élément n'augmentera pas beaucoup (peut-être de 1 à 2 nanosecondes), mais cela permettra de gagner un temps énorme sur la sauvegarde et la lecture d'un tableau depuis le disque et vers le disque.

Renate n'est pas assez pour toi ) Combien de fois il a été suggéré d'optimiser le stockage de l'histoire. D'autant plus qu'il n'y a rien à dépenser pour la compression (qui est la partie la plus gourmande en ressources), car les données arrivent initialement du serveur compressées, et seul le cache, qui est constamment utilisé, est conservé non compressé... Mais c'est là qu'intervient toujours la leçon de morale : si vous ne pouvez pas acheter un disque dur plus grand ou plus rapide, il n'y a rien à faire sur un MT. Et les VPS lents sont toujours mentionnés pour une raison quelconque.

 
Alexey Navoykov:

Renate n'est pas assez pour toi ) Combien de fois il a été suggéré d'optimiser le stockage de l'histoire. D'autant plus qu'il n'y a rien à dépenser pour la compression (qui est la partie la plus gourmande en ressources), car les données viennent à l'origine du serveur compressées, et seul le cache, qui est constamment utilisé, est conservé sous forme non compressée... Mais c'est là qu'intervient toujours la leçon de morale : si vous ne pouvez pas acheter un disque dur plus grand ou plus rapide, il n'y a rien à faire sur un MT. Et les VPS lents sont toujours mentionnés pour une raison quelconque.

Une fois de plus, le principal problème des tableaux emballés est d'organiser un accès rapide à n'importe quel élément du tableau, plutôt que de les lire séquentiellement. C'est pourquoi un format de compression (ou même un format de stockage) différent est nécessaire ici, oui tel qu'il n'a pas besoin d'être déballé et emballé. Bien sûr, une compression ~10 fois plus importante que pour le zip, le png, etc. ne fonctionnera pas, mais je pense qu'une compression 5 fois plus importante est possible.

En fait, si l'on y réfléchit, dans MqlRates, 8*4=32 octets sont alloués pour stocker les informations sur les barres d'une minute (alors que seules les barres d'une minute sont stockées), bien que dans 99% des cas, ces valeurs diffèrent de moins d'un octet d'information, c'est-à-dire que 8+1+1+1=11 octets sont presque suffisants, même s'ils ne sont pas liés aux barres précédentes. Et dans 99 % des cas, le temps diffère de la valeur précédente d'exactement 60 (c'est-à-dire que dans 99 % des cas, un bit d'information suffit - 60 ou pas 60). Et 8 octets sont alloués pour cela aussi.

 
Nikolai Semko:

Une fois de plus, le principal problème des tableaux emballés est d'organiser un accès rapide à n'importe quel élément du tableau, plutôt que de les lire séquentiellement. C'est pourquoi un format de compression (ou même un format de stockage) différent est nécessaire ici, oui tel qu'il n'a pas besoin d'être déballé et emballé. Bien sûr, les zip, png, etc. ne peuvent pas être compressés ~10 fois, mais je pense que 5 fois est possible.

Si nous parlons d'un stockage sur disque, l'accès à un élément spécifique n'a pas de sens, car l'opération de fichier elle-même est coûteuse. Par conséquent, une grande partie est lue en une seule fois. Par exemple, les fichiers d'historique de barres sont répartis par année, les ticks par mois. Et si vous voulez garder l'histoire en mémoire sous une forme emballée, en déballant constamment chaque élément à la volée, alors je crains que cela ne convienne à personne.

 

Je viens d'inventer un format de stockage qui stocke des blocs de 256 éléments MqlRates et prend 2900 octets en moyenne (la taille du bloc sera flottante), c'est-à-dire que 2900/256= ~12 octets seront alloués par structure MqlRates, ce qui est 5 fois moins, comme je le pensais.

L'accès à chaque élément de la structure MqlRates emballée est assez rapide ( 2-3 sommes, 2-3 vérifications, 2-3 décalages, c'est-à-dire guère plus d'une nanoseconde)

 
Alexey Navoykov:

Si nous parlons de stockage sur disque, l'accès à un élément particulier n'a pas de sens, car l'opération de fichier elle-même est coûteuse. Par conséquent, une grande partie est lue en une seule fois. Par exemple, les fichiers d'historique de barres sont divisés par années, les ticks sont divisés par mois. Et si vous voulez garder l'histoire en mémoire sous une forme emballée, en déballant constamment chaque élément à la volée, alors je crains que cela ne convienne à personne.

Il sera stocké sur le disque dans un format "compressé" et sera également lu en mémoire dans le même format. Il n'y aura pas de conversion vers un format complet, mais il y aura seulement un calcul au moment de la lecture d'un élément spécifique de la structure MqlRates. Et il sera beaucoup plus rapide, compte tenu du fait qu'il y aura cinq fois moins de travail avec le disque.

 
Nikolai Semko:

L'accès à chaque élément d'une structure MqlRates emballée est assez rapide.

...

Il sera stocké sur le disque dans un format "compressé" et lu dans la mémoire dans le même format. Il n'y aurait pas de conversion vers un format complet, mais seulement les calculs résultants au moment de la lecture d'un élément particulier de la structure MqlRates.

Oui, mais le concept de "rapide" dans votre cas est très relatif. Une chose est que l'utilisateur a demandé un tableau de barres, il a simplement copié une zone de la mémoire, ou a demandé une série chronologique spécifique, c'est aussi une simple copie de données avec un pas constant, égal à la taille de la structure. Il y a aussi les calculs et conversions supplémentaires pour chaque chiffre.

Bien que, personnellement, je préférerais avoir un historique compressé, afin de ne pas gaspiller de la mémoire, car j'organise de toute façon mes propres tableaux pour le stocker. Je suis donc prêt à tolérer un petit retard. Mais la plupart des autres utilisateurs vous mettraient en pièces pour cela.)

p.s. Mais idéalement, il serait bon d'avoir une telle option dans le terminal pour choisir comment l'historique est stocké en mémoire. Par exemple, si le système dispose de peu de mémoire vive, mais d'un processeur rapide, cela peut s'avérer utile.

 
Alexey Navoykov:

Oui, mais la notion de "rapide" dans votre cas est très relative. C'est une chose pour un utilisateur de demander un tableau de barres - il est juste copié une zone de la mémoire, ou demandé une série chronologique spécifique, alors c'est aussi une simple copie de données avec un pas constant, égal à la taille de la structure. Et il y a aussi les calculs et conversions supplémentaires pour chaque chiffre.

Bien que, personnellement, je préférerais avoir un historique compressé, afin de ne pas gaspiller de la mémoire, car j'organise de toute façon mes propres tableaux pour le stocker. Je suis donc prêt à tolérer un petit retard. Mais la plupart des autres utilisateurs vous mettraient en pièces pour cela.)

p.s. Bien qu'idéalement, il serait bien d'avoir une telle option dans le terminal, pour choisir le mode de stockage de l'historique en mémoire. Par exemple, si le système a peu de RAM, mais un processeur rapide, il sera très utile.

Eh bien, regardez. Je viens de mesurer les vitesses d'écriture et de lecture sur mon SDD. Il s'est avéré que le temps d'écriture et de lecture de 8 octets (1 type de valeur double ou datetime ou long) ~ 48 ns. Et selon mes calculs, le temps de lecture de 8 octets d'information à partir d'un tableau emballé est de 1-2 ns. Ainsi, alors que nous perdons 1-2 ns sur l'accès à un élément de structure, nous gagnons 48*0,8 = 38 ns pour l'écriture et la lecture du disque. En outre, nous avons multiplié par 5 la RAM et l'espace disque, et je ne parle même pas du disque dur.

Raison: