Seite 1 von 1

Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 08:54
von DePe
Ich empfange Daten über das Netzwerk in einem Thread. Wenn ich im Ereignis #PB_NetworkEvent_None von NetworkClientEvent(#) ein Delay(1) einfüge, dauert die Übertragung doppelt solange. Ohne Delay() oder mit Delay(0) wird die CPU, bw. ein Kern voll ausgelastet und die Übertragung ist doppelt so schnell.

Eine andere Software ist gleich schnell, aber lastet die CPU nicht aus, es sind nur ~ 5 %.

Ich habe schon einiges probiert, z.B. mit ZwDelayExecution() und timeBegin/EndPeriod(). Aber sobald ich irgendein 'Delay' verwende ist die Übertragung langsamer. Ohne Delay zähle ich so zwischen 0 und 900 Schleifendurchläufe im Ereignis #PB_NetworkEvent_None bis wieder Daten vorhanden sind. Die CPU ist ein langsamer Celeron J1900 mit 1,3 GHz. Ich vermute eine schnelle CPU verheizt dann die Leerlaufzeit noch besser :-)

Gibt es da eine bessere Möglichkeit für die Wartezeit beim Empfang? Oder funktioniert das nur, wenn man nicht die PureBasic Netzwerkfunktionen verwendet?

Konkret geht es um Messgeräte, wie Oszilloskope. Mit dem Programm in der Version 0.2.0.x habe ich das Problem:
http://peter.dreisiebner.at/messinstrumente/
Man kann damit im Moment nur SCPI-Kommandos senden.

Peter

Edit:
Das Problem ist eigentlich nur eines. wenn viele kleine Datenpakete empfangen werden, z.B. 3 MB in 1 KB Paketen.

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 15:51
von mk-soft
Überprüfe mal ob die CPU überhaupt ein schnelles Delay unterstützt.

Code: Alles auswählen

Case #PB_NetworkEvent_None
          Delay(1)
          i + 1
          If i > 1000
            Debug ElapsedMilliseconds() - i_t
            i_t = ElapsedMilliseconds()
            i = 0
          EndIf
P.S.
5% Auslastung finde ich schon sehr hoch
Versuch mal dieses

Code: Alles auswählen

Case #PB_NetworkEvent_None
          i + 1
          If i >= 1000
            i = 0
            Delay(10)
          EndIf

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 17:07
von DePe
Also beim ersten Code bekomme ich keine Ausgaben. Da ist das Delay(1) so lang, dass der Zähler die 1000 nie ereicht, bzw. die Antwort vom Gerät früher kommt. Die Übertragung dauert wieder doppelt so lange, die CPU-Belastung ist dafür Null.

Beim zweiten Code wird das Delay(10) so achtmal ausgeführt, danach geht es ohne Delay-Unterbrechung weiter. Da wird am Anfang auf die Antwort vom Gerät gewartet. Die Übertragung ist schnell, die CPU-Belastung dafür wieder hoch.

Die 5 % von dem anderen Programm sind eigentlich die Grundbelastung von meinem PC. Ich schaue nur im Taskmanager nach, so 3 bis 4 % sind immer da.

Peter

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 18:40
von mk-soft
Falscher Wert, zu hoch

Code: Alles auswählen

Case #PB_NetworkEvent_None
          i + 1
          If i >= 100 ; <- Hier wert suchen der passt 
            i = 0
            Delay(10)
          EndIf

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 19:13
von helpy
Da wünscht man sich eine WaitNetworkEvent-Funktion:

Code: Alles auswählen

WaitNetworkServerEvent([#Server [, Timeout]])
... und für den Client:

Code: Alles auswählen

WaitNetworkClientEvent(Connection [, Timeout])

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 08.03.2020 21:14
von DePe
Das mit der Schleife und Zähler funktioniert nicht wirklich. Entweder bleibt die CPU-Belastung hoch, oder ich bremse die Verbindung damit aus. Ich kompiliere auch immer und verwende OutputDebugString_() für Messungen.
Und ich vermute ein schneller PC wartet dann sogar öfters, da er die Schleife ja schneller abarbeitet, und so vielleicht öfters als nötig wartet. Und in der Zeit wo gewartet wird, obwohl schon wieder Daten vorhanden sind, sendet das Gerät auch nicht weiter. Das wartet auf eine Anfrage bis es die nächsten Daten sendet.
Ich verwende jetzt wieder Delay(0), vielleicht finde ich einmal eine andere Lösung.

Peter

Re: Kurzes Delay() für Netzwerk und Thread?

Verfasst: 09.03.2020 09:54
von tft
Hallo,

schau mal hier http://forums.purebasic.com/english/vie ... 13&t=20964,
und https://docs.microsoft.com/de-de/window ... out-timers.

es gibt einen High resulution Counter. Aber nicht jedes Board unterstützt das.

Code: Alles auswählen

Procedure.l TicksHQ()
  Static maxfreq.q
  Protected t.q
  If maxfreq=0
    QueryPerformanceFrequency_(@maxfreq)
    maxfreq=maxfreq/1000
  EndIf
  QueryPerformanceCounter_(@t.q)
  ProcedureReturn t/maxfreq
EndProcedure

Code: Alles auswählen

t=TicksHQ()
Repeat
  t2=TicksHQ
  If t2-t
    ; a millisecond has passed
    ; do some stuff
    t=t2
  EndIf
Until PureBasic 4.0 is released
Habe ich aus meinem Proc Pool entnommen und nicht Aktuell getestet.

Gruss TFT