Ich brauche Hilfe! Ich kann das Problem nicht lösen, ich stoße an die Grenzen der Hardware - Seite 15

 

Endlich habe ich herausgefunden, was nötig ist, und hoffe, dass diese Version endgültig ist.

Wie gesagt, alles ist einfach genug, um die wichtigsten Schritte zu teilen und zu parallelisieren:

1. a. Es wäre sehr nützlich zu wissen, wo der Anfang und das Ende jeder Sequenz liegt (deshalb habe ich beim letzten Mal vorgeschlagen, die Größen in eine separate Datei zu schreiben)

б. Sie können sie selbst analysieren, aber in diesem Fall müssen Sie zurückkommen, wenn Sie den nächsten Teil der Datei von der Festplatte lesen, um die vorherige getrimmte Sequenz zu lesen

Als nächstes werde ich die Variante 1.a in Betracht ziehen. Sie ist wahrscheinlich nicht optimal, aber sie gefällt mir besser.

2. Wenn wir die Größe der Sequenzen und die Speichergröße für einen Teil der Datei (500 MB) kennen, können wir die Größe des Teils der Datei berechnen, den wir herunterladen müssen.

3. Parallel dazu berechnen wir Koeffizienten für Sequenzen, da wir den Anfang und das Ende jeder Sequenz kennen.

4. Anfang und Ende jeder Sequenz können in der multithreaded Warteschlange gespeichert werden (die während der Berechnung von Schritt 2 gefüllt wird)

5. Berechnungsergebnis - Struktur (Array aus Struktur wo Zeit und Koeffizient + Sequenznummer))

6. Wenn die Hälfte der anfänglichen Größe des zugewiesenen Speichers (250 MB) verarbeitet ist, wird der Prozess des Neuschreibens mit der Bildung der zweiten Warteschlange mit dem Anfang und dem Ende begonnen

7. Am Ende der ersten Zeile angelangt, lesen wir aus der zweiten Zeile; am Ende der zweiten Zeile lesen wir aus der ersten Zeile.

8. Sie können gleichzeitig Koeffizienten berechnen und aus der Datei lesen.

9. Aber jedes Ergebnis der Koeffizientenberechnung muss gespeichert werden, und es ist besser, sie auf einmal in der Antwort zusammenzuführen:

Wir müssen Zusammenführungsfunktionen schreiben: zwei Folgen von Koeffizienten zu einem Teilergebnis, zwei Teilergebnisse zu einem leicht vollständigen Teilergebnis

10. Der Zusammenführungsprozess kann auch parallel durchgeführt werden.

11. Wann liegt das Ergebnis vor? Wenn die Größe der aus der Zusatzdatei gelesenen Sequenzen abgeschlossen ist, werden zwei Stapel leer, und die Berechnung der Koeffizienten ist beendet,

dann müssen wir warten, bis die Zusammenführung von Teilergebnissen abgeschlossen ist (dies kann auch über eine fadensichere Warteschlange erfolgen)

und schließlich die Teilergebnisse der verschiedenen Threads zusammenführen - Ergebnis.


Hier ist eine Variante mit maximaler Belastung von allen möglichen, vielleicht etwas besser - ich werde froh sein.

Ich brauche Funktionen:

Bildung einer Folge von Koeffizienten aus einer Eingangssequenz

Zusammenführen von zwei Koeffizientenfolgen zu einem einzigen Teilergebnis (möglicher Genauigkeitsverlust hier)

Verschmelzung von zwei Teilergebnissen zu einem einigermaßen vollständigen Teilergebnis (mit möglichen Genauigkeitseinbußen)

 
komposter:

Ich denke, dass es möglich ist, einen cleveren Mechanismus für die Teilbeladung zu erfinden, aber er muss erfunden werden.

Suchen Sie z. B. beim ersten Lesen für jeden Durchgang das letzte Geschäft, das vor dem Startdatum abgeschlossen wurde, gehen Sie zurück und lesen Sie X vorherige Geschäfte, merken Sie sich den Punkt in der Datei, an dem dieses Geschäft endet.

Danach suchen Sie das erste Geschäft in den Ergebnissen und arbeiten dann nur mit frischen Daten: Lesen Sie die Datei vom gewünschten Zeitpunkt bis zum neuen aktuellen Datum und verschieben Sie jedes Mal die Geschäfte im Array (erhalten Sie ein Array fester Größe - X Elemente).

Dies löst das Problem der mehrfachen Lesevorgänge (wir brauchen es einfach nicht) und des Speichers (nur wenn wir X Millionen Transaktionen unterbringen können).

Ja, genau das wird der Algorithmus tun.

  1. Ändern Sie die Größe aller Arrays von Geschäften auf X Elemente.
  2. Set SeekDate = StartDate.
  3. Öffnen Sie die Datei, beginnen Sie mit dem Lesen und füllen Sie nacheinander das Array der Angebote des ersten Durchgangs.
  4. Wenn die dem Durchgang entsprechenden Geschäfte beendet sind (nicht genügend X-Geschäfte), setzen Sie den Kriteriumwert = N/A und gehen Sie zum nächsten Durchgang über.
  5. Wenn Sie den Handel # (X+1) erreichen, verschieben Sie alle vorherigen Handlungen zurück (#1 wird verworfen, #2 wird #1, #X+1 wird #X).
  6. Wenn Sie ein Geschäft erreichen, dessen Eröffnungszeit >= Suchdatum ist, wird es nicht zum Array hinzugefügt:
    • Berechnung des Kriteriumswertes für die zuvor hinzugefügten Geschäfte #1 - #X
    • Kriteriumswert merken
    • die Position des Dateizeigers vor der Transaktion speichern
    • Weiter zur nächsten Sequenz
  7. Wenn die letzte Sequenz abgearbeitet wurde:
    • Die Reihe von Sequenzen durchlaufen und den besten Wert für das Kriterium finden
    • Gehen Sie zu der Position in der Datei, an der sich der letzte Abschluss der besten Sequenz befindet
    • Einlesen eines Geschäfts aus der Datei, Hinzufügen zum Array (vorherige Geschäfte werden verschoben)
    • Merken Sie sich die Position des Dateizeigers
    • Schreiben Sie das Geschäft in die Ergebnisdatei
    • Set SequentialDate = Geschäftsschlusszeit + 1
    • Wir fahren mit der Schleife durch die Sequenzen fort, mit der einzigen Bedingung, dass die Arrays bereits gefüllt sind und das Lesen ab dem gespeicherten Punkt fortgesetzt wird.

Wenn es uns gelingt, Speicher für X Millionen Transaktionen zuzuweisen(die Größe der Struktur ist im Voraus bekannt), dann können wir die Datei einmal lesen.

Ist dies nicht der Fall, müssen wir das Lesen der letzten X Geschäfte bei jeder Rückkehr zum Erinnerungszeiger hinzufügen. Dann wird die Datei zwar mehrfach, aber dennoch kostengünstig gelesen.

Die Struktur der Sequenz wird festgelegt: Nos, Trades[X], Criterion, FilePointer position. Es gibt nichts Unnötiges.

Alles, was bleibt, ist zu codieren =)

 

Was ist das wünschenswertere Ergebnis?

eine dll- oder doch eine mql-Berechnung?

 

Ja, in dieser Form ist die Aufgabe parallel - jedes Mal, wenn sichdas Suchdatum ändert,können Sie eine gleichzeitige Suche nach dem besten Kriterium auf verschiedenen Teilen der Sequenzmenge durchführen. Wir teilen sie zum Beispiel in 20 Teile auf und geben die Aufgabe an 20 Expert Advisors. Und sie sollten die Datei lesen, den Deal finden und nur die beste Reihenfolge (№№, Kriterium und Dateiposition) zurücksenden.

Ich danke Ihnen allen sehr herzlich!

 
ALXIMIKS:

Was ist das wünschenswertere Ergebnis?

dll oder doch mql zu berechnen?

Besseres mql, natürlich. Und es macht keinen Sinn, eine DLL zu schreiben, man kann auch in MT parallelisieren.
 

Ich habe nicht mit mql für ein halbes Jahr, kann ich ein wenig dumm sein, klären, wenn ich falsch bin:

Открываем файл, начинаем читать, последовательно заполняя массив сделок первого прохода 

Planen Sie, für jeden Durchlauf einen separaten Lesevorgang von der Festplatte durchzuführen? 10^6 Mal von der Festplatte gelesen?

Kann es nicht ein Problem geben, wenn man die Texte einzeln liest, anstatt sie in einem Stück zu lesen? Oder wird hier alles auf höchstem Niveau und mit solider Pufferung umgesetzt?

Wenn wir einen Handel erreichen, dessen Eröffnungszeit >= SeekDate ist (er wird nicht zum Array hinzugefügt):

  • Set SeekingDate = Geschäftsabschlusszeit + 1
  • Wir fahren mit der Schleife durch die Sequenzen fort, mit der einzigen Einschränkung, dass die Arrays bereits gefüllt sind und das Lesen ab dem gespeicherten Punkt fortgesetzt wird.

Ich sehe nicht, wo der Speicher freigegeben wird, er stapelt sich weiter.

  • Die Reihe von Sequenzen durchlaufen und den besten Wert für das Kriterium finden

Warum die gesamte Palette für ein Kriterium aufbewahren? Sie können sie bei der Berechnung eines neuen Kriteriums einfach vergleichen und das passende Kriterium behalten.

Wenn Sie die 10 besten Kriterien finden wollen, ist es besser, ein Array mit 10 Kriterien zu erstellen, es mit Werten zu füllen, es zu sortieren und dann das nächste Kriterium mit Hilfe der binären Suche einzufügen.

 
ALXIMIKS:

Planen Sie, für jeden Durchlauf ein separates Lesen von der Festplatte durchzuführen? 10^6 Mal von der Festplatte lesen?

Wir müssen ohnehin die gesamte Datei lesen. Wir können nicht alles auf einmal (von Anfang bis Ende) lesen, also müssen wir in Stücken lesen (aber wir werden trotzdem die ganze Datei erhalten).

ALXIMIKS:

Kann es nicht ein Problem geben, wenn man ein Stück auf einmal liest, anstatt das ganze Stück auf einmal zu lesen? Oder wird hier alles auf höchstem Niveau und mit solider Pufferung umgesetzt?

Ein Chunk wird gelesen. Die Größe des Chunks wird durch die Anzahl der Transaktionen vor dem Seeking Date bestimmt, die in einer bestimmten Reihenfolge waren.

ALXIMIKS:

Ich sehe nicht, wo der Speicher freigegeben wird, er stapelt sich weiter.

Der Speicher wird einmal für ein Array von Sequenzstrukturen zugewiesen.

Die Struktur der Sequenz umfasst: Nr., Array der Strukturen aller Transaktionen der Sequenz [X], Wert des Kriteriums, Position des Dateizeigers.

Der nächste Schritt ist nur das Füllen der Strukturelemente (einschließlich der Arrays von Geschäften). Die Geschäfte im Array werden verschoben, so dass sich immer nur X Geschäfte jeder Sequenz im Speicher befinden.

ALXIMIKS:

Wenn Sie die 10 besten Kriterien finden wollen, ist es besser, ein Array mit 10 Kriterien zu erstellen, es mit Werten zu füllen, es zu sortieren und dann das nächste Kriterium mit Hilfe der binären Suche einzufügen.

Auch für die Parallelisierung.

Aber die Eliminierung eines Doubles aus einer Struktur, die ein Array von Deal-Strukturen enthält, macht im Rahmen der Aufgabe keinen Unterschied.

 

Weitergabe der Ergebnisse meiner Forschung.

Binäre Cache-Datei von 7529 MB liest:

  • Von der Festplatte: in 212,3 Sekunden (35,46 MB/Sek.)
  • Von der RAM-Disk: in 88,1 Sekunden (85,46 MB/Sek.)
Es ist schwer, den Unterschied als kosmisch zu bezeichnen, obwohl ich die gängigste Festplatte habe (allerdings ist der Speicher auch nicht schnell).

Fazit: Der Geschwindigkeitszuwachs beim Lesen einer großen Datei über die RAM-Disk beträgt etwa das 2,5-fache.

 

Wäre die Datei nicht innerhalb der Sequenzen, sondern global (nach allen Sequenzen) nach dem Zeitpunkt der Erledigung sortiert, wäre der folgende Algorithmus möglich:

- Berechnen Sie das Kriterium für einen Handel, betrachten Sie ihn als Kandidaten

- Wir berechnen Kriterien für Geschäfte, die innerhalb dieses Geschäfts beginnen. Wenn wir das beste erhalten, ändern wir den Kandidaten, wenn wir es nicht erhalten, betrachten wir den Kandidaten als ausgewählt und beginnen einen neuen Zyklus ab dem Datum seines Abschlusses.

Wir können auch nach Abschlusszeit sortieren - in diesem Fall beginnen wir am Ende

Es ist klar, dass die Datei für die Berechnung eines Kriteriums eine laufende Nummer für jedes Geschäft enthalten muss.

Das Neusortieren einer solchen Datei ist wahrscheinlich auch keine lustige Sache, wir können versuchen, sie gleich "richtig" zu schreiben. Das heißt, dass nicht ganze Sequenzen nacheinander generiert werden, sondern eine Transaktion für jede Sequenz und ein Zwischenspeicher mit Intelligenz beim Schreiben verwendet wird. Für einige Generierungsalgorithmen kann dies natürlich unannehmbar sein.

 
Candid:

Wäre die Datei nicht innerhalb der Sequenzen, sondern global (nach allen Sequenzen) nach dem Zeitpunkt der Abschlüsse sortiert, wäre ein solcher Algorithmus möglich:

- Berechnen Sie das Kriterium für das Geschäft, betrachten Sie es als einen Kandidaten

Angenommen, ich nehme eine solche Datei auf (ich konvertiere einfach die aktuelle Datei, auch wenn das 15 Stunden Computerzeit kostet).

Aber dann - beim ersten Punkt - gibt es einen Haken. Wie berechne ich das Kriterium für die letzten X Abschlüsse der Sequenz, wenn ich eine solche Datei habe?

Auch hier gilt, dass das Kriterium nicht einmalig berechnet werden kann, da sich seine Parameter ändern können.