Über den MT5-Code-Profiler - Seite 3

 

Fortsetzung folgt:


Welche der Zeilen (1, 2 oder 3) ist noch ressourcenintensiv?

Ich kann nicht verstehen, wie das "schwere" iTime, das 55% der Zeit des gesamten Programms beansprucht, nur 0,81% Self CPU anzeigt?
Und umgekehrt - warum zeigt die öffnende Klammer (1) und die einfachste Bedingung (2, trifft sehr selten zu) 33,84% Self CPU?

Warum werden Self CPU und Total CPU nicht abgeglichen?


Die Funktion ist wirklich schwer, aber die ganze Schwere liegt weiter unten im Code. Und der Profiler schlägt vor, nach einem Ersatz für iTime und zwei boolesche Variablen zu suchen?!

Ich verstehe offensichtlich etwas nicht.

 
Andrey Khatimlianskii:

Ich übersehe offensichtlich etwas.

Vielleicht ein Ausrutscher?

 
Andrei Trukhanovich:

Vielleicht ein Ausrutscher?

Sieht nicht so aus, die Zahlen in dem Bericht sind die gleichen.

 
Andrey Khatimlianskii:

Ilyas, helfen Sie mir, auch das herauszufinden.

1. Warum kann ein leerer Funktionsaufruf 34,5 % der Self-CPU in Anspruch nehmen? Gleichzeitig taucht der Aufruf der darauf folgenden Funktion, deren Interna 38,16 % der Gesamt-CPU beanspruchen, in dem Bericht überhaupt nicht auf?


Funktionscode:



2. Dieses Beispiel zeigt das zweite Problem: Die Zeile mit TimeCurrent() dauert nicht nur innerhalb der Funktion, sondern im Programm allgemein unangemessen lange:

Bevor ich den Körper von CheckTimeSeries() auskommentiert habe, lag die Hauptlast auf der Zeile TimeCurrent().

Ist das wirklich eine so schwere Aufgabe? Wodurch soll sie ersetzt werden? Oder wie kann man es wirtschaftlich machen (Zwischenspeicherung innerhalb einer Schleife der Programmausführung)?

Wo immer ich kann, spare ich Berechnungen, indem ich sie ausdünne (einmal pro Takt, einmal alle X Sekunden, einmal alle Y ms, usw.). Es stellt sich jedoch heraus, dass die Prüfung selbst, d. h. die Durchführung der Berechnungen, recht ressourcenintensiv ist.


Vielen Dank für die Hilfe.

1) Ohne Code ist es schwer zu sagen, warum diese Statistiken so schlecht sind, vielleicht wegen der Optimierung

2) Warum nicht versuchen, die Zeit in der Timer-Funktion vor der Schleife zu erhalten und sie als Parameter weiterzugeben, was bringt es, diese Funktion mindestens 2*N Mal in der Schleife aufzurufen?

 
Andrey Khatimlianskii:

Als Folgemaßnahme:


Welche der Zeilen (1, 2 oder 3) ist noch ressourcenintensiv?

Ich kann nicht verstehen, wie das "schwere" iTime, das 55% der Zeit des gesamten Programms beansprucht, nur 0,81% Self CPU anzeigt?
Und umgekehrt - warum zeigt die öffnende Klammer (1) und die einfachste Bedingung (2, trifft sehr selten zu) 33,84% Self CPU?

Warum werden Self CPU und Total CPU nicht abgeglichen?


Die Funktion ist wirklich schwer, aber die ganze Schwere liegt weiter unten im Code. Und der Profiler schlägt vor, nach einem Ersatz für iTime und zwei boolesche Variablen zu suchen?!

Ich verstehe offensichtlich etwas nicht.

1) Ich werde davon ausgehen, dass die Funktion wurde inlined

2) Die Zähler sind wirklich unabhängig, SelfCPU ist die Last auf die Funktion Code, ohne Berücksichtigung der aufgerufenen Funktionen, in den Code gegeben, es ist ein IF Opener (Verzweigung)

3) TotalCPU-Zähler zeigt die Auslastung des Ausführungszweiges an, für alle Aufrufe in diesem Zweig des Programms

 

Sollten es nicht immer 100 % sein? Oder sogar etwas weniger, wenn man auch @global_initializations und @global_deinitializations berücksichtigt.

Hier ist mehr als 102% ...(Build 3003 auf historischen Daten).

 
Ilyas :

1) Ich werde davon ausgehen, dass die Funktion wurde inlined

2) Die Zähler sind wirklich nicht verwandt, SelfCPU ist die Last auf die Funktion Code, ohne Berücksichtigung der aufgerufenen Funktionen, in der obigen Code, es ist ein IF Opener (Verzweigung)

3) Der TotalCPU-Zähler zeigt die Auslastung eines Ausführungszweigs für alle Aufrufe in diesem Zweig des Programms an.

Wie nützlich ist sie? Es ist offensichtlich, dass die IF-Anweisung an sich eine geringe CPU-Belastung hat. Sollte sie nicht auch Funktionsaufrufe enthalten?

Auf jeden Fall. Wie zu verstehen (anhand von Andrews Beispiel):

if(!simulated) taking 3.86% ?!?

Was ist damit?


wo wir uns in der gleichen Funktion Tick () zu befinden scheinen!

Ich möchte Profiler wirklich nutzen und verstehen, aber nichts davon ergibt Sinn. Entschuldigung.

Was ist zu tun? Wie können wir helfen?

 
Ilyas:

1) Ohne Code ist es schwer zu sagen, warum die Statistiken so hoch sind, wahrscheinlich wegen der Optimierung

2) Warum nicht versuchen, die Zeit in der Timer-Funktion vor der Schleife zu erhalten und sie als Parameter weiterzugeben, was ist der Sinn, diese Funktion mindestens 2*N Mal in der Schleife aufzurufen?

Vielen Dank für die Antworten!

1) Ich kann es mit einem einfachen Code kaum reproduzieren, ja. Und ich bin nicht bereit, das ganze Projekt zu verraten.

2) In diesem speziellen Fall stimme ich zu.

Aber es gibt viele andere Klassen, die die gleiche oder eine ähnliche Prüfung verwenden und auf TimeCurrent oder GetTickCount nicht verzichten können.
Wie kann man ihren Aufruf so optimieren, dass sie nicht mehrmals denselben Wert anfordern?

Und ist TimeCurrent wirklich so schwerfällig, dass es sich im Hintergrund von wirklich schweren Berechnungen bemerkbar macht (selbst wenn sie alle 1 oder 5 Minuten durchgeführt werden)?
Oder habe ich mich wieder geirrt und 38,16% der Gesamt-CPU / 26,07% der Selbst-CPU wurde durch die Überprüfung von if selbst (ohneTimeCurrent Funktionsaufruf) belegt? Aber warum ist das so?


Ilyas:

1) Ich werde davon ausgehen, die Funktion war inline

2) Die Zähler sind wirklich nicht verwandt, SelfCPU ist die Last auf die Funktion Code, ohne Berücksichtigung der aufgerufenen Funktionen, in der obigen Code, ist es die IF-Öffner (Verzweigung)

3) TotalCPU-Zähler zeigt die Auslastung eines Ausführungszweiges durch alle Aufrufe in diesem Zweig des Programms

1) Es hilft nicht zu verstehen, warum eine so gefräßige Eröffnungsparenthese. Wie ist dies zu interpretieren?

2) Über SelfCPU ist jetzt klar, danke. Es ist ein Haufen Funktionscode ohne Rücksicht auf die aufgerufenen Funktionen.

Dies erklärt auch die niedrige SelfCPU des Strings mit iTime - sie wurde nur sehr selten erreicht, sie wurde nur selten aufgerufen.

Aber warum ist TotalCPU so hoch? Oder zeigt es die Auslastung aller iTime- (und anderer CopyXXX-?) Funktionen im gesamten Programm?

 
Andrey Khatimlianskii:

Ich danke Ihnen für Ihre Antworten!

1) Ich glaube nicht, dass ich es mit einfachem Code reproduzieren kann, ja. Und ich bin nicht bereit, das ganze Projekt zu verraten.

2) In diesem speziellen Fall stimme ich zu.

Aber es gibt viele andere Klassen, die die gleiche oder eine ähnliche Prüfung verwenden und auf TimeCurrent oder GetTickCount nicht verzichten können.
Wie kann man ihren Aufruf so optimieren, dass sie nicht mehrmals denselben Wert anfordern?

Und ist TimeCurrent wirklich so schwerfällig, dass es sich im Hintergrund von wirklich schweren Berechnungen bemerkbar macht (selbst wenn sie alle 1 oder 5 Minuten durchgeführt werden)?
Oder habe ich mich wieder geirrt und 38,16% der Gesamt-CPU / 26,07% der Selbst-CPU wurden von der Prüfung selbst belegt (ohneTimeCurrent Funktionsaufruf)? Aber warum ist es dann so?


1) Es hilft nicht zu verstehen, warum eine so gefräßige Eröffnungsparenthese. Wie ist dies zu interpretieren?

2) Über SelfCPU ist jetzt klar, danke. Es ist ein Haufen Funktionscode ohne Rücksicht auf die aufgerufenen Funktionen.

Dies erklärt auch die niedrige SelfCPU des Strings mit iTime - sie wurde nur sehr selten erreicht, sie wurde nur selten aufgerufen.

Aber warum eine so große TotalCPU? Oder zeigt es die Auslastung aller iTime- (und anderer CopyXXX-?) Funktionen im gesamten Programm?

Bitte nehmen Sie einen beliebigen Code aus der Standardauslieferung, lesen Sie ihn Korrektur und stellen Sie auf dieser Grundlage Fragen. Dies ermöglicht eine reproduzierbare Beurteilung der Situation und liefert genaue Antworten.

Andernfalls ist es sinnlos, kleine Teile Ihres Codes für Profiler-Berichte zu beantworten. Hinter den Kulissen wird eine enorme Menge an Optimierungsarbeit geleistet, die Ihren gesamten Code in eine völlig andere, durcheinandergewürfelte und eingebettete Darstellung verwandelt.


Zur Information: Gott bewahre, dass 1 von 100 C++-Programmierern den Profiler benutzen und seine Berichte verstehen kann. Das ist die Schuld des Optimierers für nativen Code.

 
Alain Verleyen:

Auf jeden Fall. Wie zu verstehen (anhand von Andrews Beispiel):

if(!simulated) taking 3.86% ?!?

Ja, ohne Berücksichtigung externer Funktionsaufrufe ist SelfCPU nicht sehr informativ. Nur auf der untersten Ebene, wo native MQL-Funktionen verwendet werden, sehen Sie die tatsächliche Belastung.
Aber in diesem Fall wird nicht klar, von welchen Stellen diese Funktionen häufiger aufgerufen werden (und mehr verbrauchen), und von welchen es einzelne Aufrufe gibt! Was nützt es mir, wenn ich weiß, dass die Funktionen KopierenXXX und BestellenXXX die meiste Zeit verbrauchen? Ich muss wissen, von welchen Teilen meines Programms sie zu oft/ineffizient aufgerufen werden.

Ich denke, dafür ist der Modus in Verbindung mit TotalCPU gedacht. Ich werde mich damit befassen. Aber bis jetzt sehe ich dort sogar komplett auskommentierte Zeilen (!).

Grund der Beschwerde: