Fehler, Irrtümer, Fragen - Seite 2284

 
Nikolai Semko:

Die Ticks werden nicht im RAM gespeichert. Soweit ich weiß, werden sie nach Bedarf heruntergeladen, und zwar stückweise.

Wenn durch tatsächliche Zecken, dann ja.

In einem einzigen Durchgang können Sie Statistiken darüber einsehen, wie viel Speicherplatz für die Speicherung von Ticks verwendet wird. Bei der Optimierung werden nicht mehr als 320 Megabyte auf einmal im Speicher abgelegt. Der Rest wird auf der Festplatte gespeichert.

Wir erwägen nun eine Lösung, um alle Ticks im gemeinsamen Speicher zu halten, so dass alle lokalen Agenten aus diesem Speicher lesen können. Dann gibt es keine Festplattenzugriffe, und die Optimierung wird schneller.

 
Slava:

Wenn es sich um tatsächliche Zecken handelt, ja.

Es ist möglich, Statistiken darüber zu sehen, wie viel Speicherplatz für die Speicherung von Ticks in einem einzigen Durchgang verwendet wird. Bei der Optimierung werden nicht mehr als 320 Megabyte auf einmal im Speicher abgelegt. Alles andere befindet sich auf der Festplatte.

Wir erwägen nun eine Lösung, um alle Ticks in einem gemeinsamen Speicher zu halten, so dass alle lokalen Agenten aus diesem Speicher lesen können. Dann gibt es keine Festplattenzugriffe mehr und die Optimierung wird schneller sein.

Ja, dies ist eine Archivierung. Wenn ich es richtig verstehe, werden jetzt die Ticks und Minutenbalken ungepackt auf der Festplatte und im Speicher gespeichert, d.h. der Balken(MqlRates-Struktur) ist 60 Bytes groß, und der Tick(MqlTick-Struktur) ist 52 Bytes groß.
Es ist furchtbar! Hier muss schon lange etwas getan werden.

Ich verstehe, dass das Hauptproblem von komprimierten Arrays die Organisation eines schnellen Zugriffs auf jedes Array-Element ist.

Aber selbst wenn wir nur jedes 256. Element des Arrays ausgepackt lassen und in den anderen Elementen nur Inkremente zu den ausgepackten Elementen speichern, können wir sehen, dass die Array-Größe um das 4-5-fache reduziert wird und die Zugriffszeit auf jedes Element nicht viel zunimmt (vielleicht 1-2 Nanosekunden), aber es wird enorme Zeit beim Speichern und Lesen des Arrays von der Festplatte und auf die Festplatte sparen.

 
fxsaber:
Warum wird die SSD während der Optimierung ständig angesprochen (das Licht flackert in hoher Frequenz)?

Deshalb verwende ich keine Ticks, sondern eine logarithmische Datenstruktur(ich habe bereits darüber berichtet), die zu einem bestimmten Zeitpunkt aus ein paar tausend Ticks besteht, dann ein paar tausend Minutenbalken, 2000 M2, 2000 M5, M10, M30, H1, H3, H6, H12, D1, W1... alle MN1-Stäbe.
Diese Struktur der vollständigen Verlaufsdaten wird zu jedem Zeitpunkt von weniger als einer Millisekunde gebildet und belegt nur 1,5 MB im RAM (eigentlich nicht einmal im RAM, sondern im Cache des Prozessors). Und alle Algorithmen, die für diese Struktur geerdet sind, fliegen einfach.

Schließlich ist unser Sehvermögen auf derselben logarithmischen Skala aufgebaut: Je weiter wir schauen, desto weniger nehmen wir kleine Details wahr.

Wenn in nicht allzu ferner Zukunft Computer nur noch einen einzigen physischen Speicherbaustein (Festplatte, Arbeitsspeicher, Prozessor-Cache) haben, nämlich den Prozessor-Cache mit 13 Nullen darin, dann werde auch ich auf Ticks umsteigen :))

...

Obwohl, vielleicht liegt es an mir, denn bei einer solchen Datenstruktur wird bei der Optimierung auch die Glühbirne flackern. Immerhin werden die Zecken noch geladen :((

 
Slava:

Wenn es sich um tatsächliche Zecken handelt, ja.

Es ist möglich, Statistiken darüber zu sehen, wie viel Speicherplatz für die Speicherung von Ticks in einem einzigen Durchgang verwendet wird. Bei der Optimierung werden nicht mehr als 320 Megabyte auf einmal im Speicher abgelegt. Alles andere befindet sich auf der Festplatte.

Wir erwägen nun eine Lösung, um alle Ticks im gemeinsamen Speicher zu halten, so dass alle lokalen Agenten aus diesem Speicher lesen können. Dann gibt es keinen Zugriff auf die Festplatte, und die Optimierung wird schneller sein.

Beginnen wir mit dem Optimierungsprotokoll

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'

Während dieser 7,5 Stunden wurde sehr häufig auf die SSD zugegriffen. Wenn die Ticks bei jedem Durchlauf gelesen wurden, ergibt das einen Durchschnitt von 26 Mal pro Sekunde für 7,5 Stunden. Daher ein so wildes Geblinke - mehr als 700 Tausend Lesungen.


Protokoll eines einzelnen Laufs

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

Wie man sieht, werden ~130K Ticks und 60K Bars verwendet (der Modus "Gesamte Historie" ist im Tester ausgewählt). D.h. ein sehr kleiner Teil der Geschichte.

Die Historie des benutzerdefinierten Symbols im Terminal enthält die folgende Menge an Historiendaten

Saved ticks = 133331
Generated Rates = 60609

D.h. in der Geschichte des Symbols ist sehr wenig mehr als der Tester verwendet.


ZS Es ist schade, sich die SSD anzusehen... Wie viel schneller könnte der Optimize sein? Seltsam, dass das Betriebssystem diese Daten nicht zwischenspeichert, da es sich um weniger als 7 MB an Ticks in unkomprimierter Form handelt.

 
Nikolai Semko:

Aber selbst wenn wir nur jedes 256. Element eines Arrays ungepackt speichern und nur Inkremente zu den ungepackten Elementen speichern, wird sich die Größe eines Arrays um das 4-5-fache verringern, während sich die Zugriffszeit auf jedes Element nicht wesentlich erhöht (vielleicht um 1-2 Nanosekunden), aber es wird eine enorme Zeitersparnis beim Speichern und Lesen eines Arrays von der Festplatte und auf die Festplatte bedeuten.

Renate ist nicht genug für Sie ) Wie oft wurde schon vorgeschlagen, die Speicherung der Historie zu optimieren. Zumal nichts für die Komprimierung aufgewendet werden muss (was der ressourcenintensivste Teil ist), da die Daten zunächst komprimiert vom Server kommen und nur der Cache, der ständig benutzt wird, ungepackt bleibt... Aber das ist der Punkt, an dem die Belehrung immer kommt: Wenn man keine größere oder schnellere Festplatte kaufen kann, gibt es auf einem MT nichts zu tun. Und langsame VPS werden aus irgendeinem Grund immer erwähnt.

 
Alexey Navoykov:

Renate ist nicht genug für Sie ) Wie oft wurde schon vorgeschlagen, die Speicherung der Historie zu optimieren. Zumal nichts für die Komprimierung ausgegeben werden muss (was der ressourcenintensivste Teil ist), da die Daten ursprünglich komprimiert vom Server kommen und nur der Cache, der ständig benutzt wird, in ungepackter Form erhalten bleibt... Aber das ist der Punkt, an dem die Belehrung immer kommt: Wenn man keine größere oder schnellere Festplatte kaufen kann, gibt es auf einem MT nichts zu tun. Und langsame VPS werden aus irgendeinem Grund immer erwähnt.

Auch hier besteht das Hauptproblem bei gepackten Arrays darin, den schnellen Zugriff auf jedes Element des Arrays zu organisieren, anstatt sie nacheinander zu lesen. Deshalb ist hier ein anderes Komprimierungsformat (oder besser gesagt, ein anderes Speicherformat) erforderlich, und zwar so, dass es nicht ausgepackt und gepackt werden muss. Die ~10-fache Komprimierung wie bei zip, png usw. wird natürlich nicht funktionieren, aber ich denke, das 5-fache ist möglich.

Nun, wenn wir darüber nachdenken, werden in MqlRates 8*4=32 Bytes für die Speicherung von Informationen über Ein-Minuten-Balken zugewiesen (während nur Ein-Minuten-Balken gespeichert werden), obwohl sich diese Werte in 99% der Fälle um weniger als ein Byte an Informationen unterscheiden, d.h. 8+1+1+1=11 Bytes sind fast genug, auch wenn sie nicht an vorherige Balken gebunden sind. Und die Zeit weicht in 99 % der Fälle um genau 60 vom vorherigen Wert ab (d. h. in 99 % der Fälle reicht 1 Bit an Information - 60 oder nicht 60). Auch hierfür sind 8 Bytes vorgesehen.

 
Nikolai Semko:

Auch hier besteht das Hauptproblem bei gepackten Arrays darin, den schnellen Zugriff auf jedes Arrayelement zu organisieren, anstatt sie nacheinander zu lesen. Deshalb ist hier ein anderes Komprimierungsformat (oder besser gesagt, ein anderes Speicherformat) erforderlich, und zwar so, dass es nicht ausgepackt und gepackt werden muss. Natürlich können zip, png, etc. nicht ~10 Mal komprimiert werden, aber ich denke, 5 Mal ist möglich.

Wenn es um die Speicherung auf der Festplatte geht, macht der Zugriff auf ein bestimmtes Element keinen Sinn, da die Datei-Operation selbst kostspielig ist. Daher wird ein großer Teil auf einmal gelesen. Zum Beispiel sind die Bar-History-Dateien nach Jahren und die Ticks nach Monaten unterteilt. Und wenn Sie meinen, die Geschichte in gepackter Form im Speicher zu halten, indem Sie jedes Element immer wieder auspacken, dann fürchte ich, dass das niemandem gefallen wird.

 

Ich habe gerade ein Speicherformat erfunden, das Blöcke von 256 MqlRates-Elementen speichert und im Durchschnitt 2900 Bytes benötigt (die Blockgröße wird gleitend sein), d.h. 2900/256= ~12 Bytes werden für eine MqlRates-Struktur zugewiesen, was fünfmal weniger ist, als ich dachte.

Der Zugriff auf jedes Element der gepackten MqlRates-Struktur ist schnell genug (2-3 Summen, 2-3 Prüfungen, 2-3 Verschiebungen, d.h. kaum mehr als 1 Nanosekunde)

 
Alexey Navoykov:

Wenn es um die Speicherung auf der Festplatte geht, macht es keinen Sinn, auf ein bestimmtes Element zuzugreifen, da die Datei-Operation selbst kostspielig ist. Daher wird ein großer Teil auf einmal gelesen. Zum Beispiel sind die Dateien der Balkenhistorie nach Jahren aufgeteilt, die Ticks nach Monaten. Und wenn Sie meinen, die Geschichte im Speicher in gepackter Form aufzubewahren, indem Sie jedes Element immer wieder auspacken, dann fürchte ich, dass das niemandem gefallen wird.

Sie werden in einem "komprimierten" Format auf der Festplatte gespeichert und im gleichen Format in den Speicher eingelesen. Es erfolgt keine Konvertierung in ein vollständiges Format, sondern nur eine Berechnung zum Zeitpunkt des Lesens eines bestimmten Elements der MqlRates-Struktur. Und es wird viel schneller sein, wenn man bedenkt, dass es fünfmal weniger Arbeit mit der Festplatte geben wird.

 
Nikolai Semko:

Der Zugriff auf jedes Element einer gepackten MqlRates-Struktur ist recht schnell

...

Sie wird in einem "komprimierten" Format auf der Festplatte gespeichert und im gleichen Format in den Speicher eingelesen. Es würde keine Konvertierung in ein vollständiges Format erfolgen, sondern nur die sich daraus ergebenden Berechnungen zum Zeitpunkt des Lesens eines bestimmten Elements der MqlRates-Struktur.

Ja, aber das Konzept von "schnell" ist in Ihrem Fall sehr relativ. Eine Sache ist, dass der Benutzer ein Array von Balken angefordert hat, er hat einfach einen Abschnitt des Speichers kopiert, oder eine bestimmte Zeitreihe angefordert, es ist auch ein einfaches Kopieren von Daten mit konstantem Schritt, gleich der Größe der Struktur. Außerdem gibt es zusätzliche Berechnungen und Umrechnungen für jede Zahl.

Obwohl ich persönlich eine komprimierte Historie bevorzugen würde, um keinen Speicher zu verschwenden, da ich ohnehin meine eigenen Arrays für die Speicherung organisiere. Ich bin also bereit, eine kleine Verzögerung in Kauf zu nehmen. Aber die meisten anderen Benutzer würden Sie dafür in Stücke reißen)

p.s. Idealerweise wäre es jedoch schön, eine solche Option im Terminal zu haben, um zu wählen, wie der Verlauf im Speicher abgelegt wird. Wenn das System z. B. nur wenig Arbeitsspeicher, aber einen schnellen Prozessor hat, wäre dies sehr nützlich.