VisualBasic Unabhängigen Präzisionstimer

H

Housechen

Gast
Alllso:
Ich habe einen Benchmark erschaffen, der bis zu 4 Kerne unterstützt und perfekt auslastet. Soweit so gut, jedoch soll dabei die Zeit gestoppt werden.
Dabei habe ich 2 Probleme:
1. Der Windooftimer ist verdammt ungenau.
2. Der Timer bleibt einfach stehen bei hoher Last. Erst wenn ich die Priorität der Thread auf BelowNormal setze, funktioniert er halbwegs. Das ist dann allerdings zum Leid der Threads, da jedes Hintergrundprogramm (Standardmäßige Priorität = Normal) mehr Aufmerksamkeit bekommt.

Ich suche daher einen präzisen Timer (10ms Genauigkeit, 1ms wäre natürlich perfekt), der prioritätsunabhängig arbeitet. Ich hoffe mir kann jemand helfen.

Danke im voraus!
 
Wie gesagt, ist damit eine genaue lastunabhängige Messung möglich?

Edit: Was ist denn mit der Klasse Stopwatch? Misst sie zuverlässig genug?
 
Zuletzt bearbeitet:
Hallo,

mit einem Timer löst du ja ein Event aus, also bist du abhängig von dem OS.
Wenn ich dich richtig verstanden habe und du eine bestimmte Zeit messen willst, dann würde ich QueryPerformanceCounter / QueryPerformanceFrequency benutzen.

Wenn du wirklich ein Event brauchst und du das unbedingt mit einem Timer machen möchtest, dann gibt es in der WinAPI noch einen Multimedia Timer der etwas genauer als der normale Timer ist. Ich würde aber an deiner stelle komplett auf Timer verzichten.
Hat den Vorteil, das dein Programm nicht die Nachrichtenschleife abarbeiten muss und du etwas unabhängiger vom OS bist.
 
Danke.
Ich habe bis jetzt mit Stopwatch in ms solide Ergebnisse erzielt, unabhängig von der Priorität der anderen Threads.
Anderes Problem:
Ich wollte sowas wie ein Status-Logfile machen, realisiert in einer Textbox.
Hier einer der 4 Threads, sie sind so aufgebaut:

Code:
    Shared Sub Thread1()
        For i As Integer = ....
'Iteration
        Next
        Finished1 = 1
    End Sub

Ich würde gerne am Anfang und am Ende folgenden Befehl in den Thread reinhauen:

Anfang:
Code:
FormBenchmark.txtLog.Text = FormBenchmark.txtLog.Text & "Starting Thread 1" & vbCrLf

Ende:
Code:
FormBenchmark.txtLog.Text = FormBenchmark.txtLog.Text & "Thread 1 finished in " & FormBenchmark.Zeit.ElapsedMilliseconds & vbCrLf

Nur wird nichts in die Textbox txtLog geschrieben. Eine MsgBox wird aber verarbeitet bzw. erscheint an diesen Stellen.
Jemand eine Idee dazu?

Seit übrigens relativ flott heute. Weiter so!
 
Zuletzt bearbeitet:
Hi,

das liegt daran, dass sich die TextBox in einem anderen Thread befindet.
Leider hab ich lange nicht mehr mit VB gearbeitet und mit Threads noch weniger. Folgendes sollte in etwa gehen, ich weiss nur nicht inwiefern das "schöner" Code ist *g*

Code:
    Delegate Sub ChangeTextFromThread(ByVal NewText As String)

    Private Shared _changer As New ChangeTextFromThread(AddressOf AppendText)

    Private Shared Sub Thread1()
        _changer.Invoke("Starting Thread 1")

        'iterationen

        _changer.Invoke("Thread1 finnished...")
    End Sub

    Private Sub AppendText(ByVal NewText As String)
        TextBox1.Text &= NewText & ControlChars.NewLine
    End Sub
 
Danke!:)
Werde das morgen mal ausprobieren, mir scheint es richtig zu sein.:)


So, mein neues Problem:
Diesmal soll´s ein primzahlenberechnender Stresstest werden, siehe Prime95 zum Beispiel.
Dazu wollte ich einen bestimmten Zahlenbereich auf Primzahlen überprüfen, undzwar mit dem "Flexiblen Lucas-test".
Nur müssen für die 2. vorhandene Bedingung alle Primfaktoren bestimmt werden. Diese würde ich dann bestimmen und "sammeln". Nur macht mir das Sammeln einige Schwierigkeiten.
Ich habe mich in zig HowTos durchgeblättert, und denke mal, dass mir am ehesten eine "Klasse" hilft, nur weiß ich nicht, wie die Routine automatisch einen Primfaktor hinzufügen kann. Die "For Each"-Methode macht mir auch Sorgen, wenn ich die Schleife für jede Zahl dieser Klasse, also für jeden Primfaktor, der Klasse "Primfaktoren" raussuchen will, meckert der wegen Parametern.
For Each ??? in/of/?... ???
Code...
Next
Wie kriege ich das am Besten hin?
Google half mir hier nicht weiter, ich benutze wohl die falschen Unterbegriffe der Klassen, also ich kenne mich nicht in der Klassenstruktur aus, wie´s weitergeht. Zum Beispiel Klasse-Apfelbaum--->Stamm--->Ast--->Zweig--->Apfel. Wie kann ich das in VB.net-Klassen alles nennen?

Wiedermal:
Danke im voraus!


EDIT:
Keiner ´ne Idee?
 
Zuletzt bearbeitet:
Sammeln könntest du das in ner List<-datentyp-> wenn ich das richtig verstanden habe, die geschichte mit den klassen... keine Ahnung was du meinst :)
 
Wenn du wirklich gescheite Zeitmessung haben willst, würde ich einfach das TSC-Register der CPU auslesen. Das ist ein MSR, dass periodisch inkrementiert wird. Für gewöhnlich mit der maximalen Taktfrequenz der CPU. Es zählt unabhängig von der Taktfrequenz, Idle-Zeiten usw.
Zum Auslesen brauchst du nur einen Assembler-Befehl (rdtsc). Näheres kannst du z.B. dem Intel Handbuch für Programmierer entnehmen. Und da das ganze komplett in Hardware ist, ist, beeinflusst es die übrigen CPU-Funktion nur minimal.

Willst du deinen Benchmark in VB.net schreiben? Du weißt, dass die Programme nur in der Virtual Machine des .net-Frameworks laufen? Und dass da so schöne Dinge wie die Garbage Collection dir bei solchen Messungen das Ergebnis ganz schön verfälschen können?
 
1.) Mit DateTime.Now bekommst du die Systemzeit auf 15.625ms genau (1/64). Sind fast 10ms.

2.) Der Timer bleibt nicht stehen. Der läuft schon korrekt. Es funktioniert nur der Thread, der die Werte nicht mehr, weil er keine CPU bekommt. Du kannst aber auch im selben Thread das Datum auslesen.

3.) Ich würde generell Prioritäten vergeben für Threads. Generell gelten folgende Richtlinien:
a) Threads mit GUI Behandlung vor Rechenthreads
b) Threads mit viel E/A vor Threads mit viel CPU-Last
c) Kurze Threads vor langen
 
@Limit:
Du kannst mir dann doch bei C++ helfen.
Ich brauche so´n kleinen Zettel wo einige Sachen geklärt werden:

-Variablen wie Integer und ganz besonders String geklarieren.
-If, Case, While, Do, For-Schleife
-Arbeiten mit Windows-Forms (Ok, das ja nicht unbedingt)
-Umgang mit Variablen (Ich hatte z.B. ein Problem den Wert einer Integer-Variable in einer MessageBox auszugeben oO)
 
Cyba_Mephisto schrieb:
@Limit:
Du kannst mir dann doch bei C++ helfen.
Ich brauche so´n kleinen Zettel wo einige Sachen geklärt werden:

-Variablen wie Integer und ganz besonders String geklarieren.
-If, Case, While, Do, For-Schleife
-Arbeiten mit Windows-Forms (Ok, das ja nicht unbedingt)
-Umgang mit Variablen (Ich hatte z.B. ein Problem den Wert einer Integer-Variable in einer MessageBox auszugeben oO)

Tut mir leid, aber für ein komplettes Tutorial habe ich im Augenblick wirklich nicht die Zeit. Wenn du aber konkrete Fragen hast, werd ich gerne versuchen sie zu beantworten.

Erstmal ist die Frage, ob du einen Benchmark in C oder in C++ schreiben willst. Ein Benchmark sollte möglichst wenig Speicher verbrauchen. Wenn deine ganzes GUI-Zeug ständig den eigentlich Benchmark aus dem Cache haut, verfälscht das das Ergebnis stark. Daher würde ich mir überlegen das Programm nicht aufzuteilen.

Benchmark-Prozess:
- sollte stark optimiert werden (MMX/SSE/...)
- hat keine GUI
- übernimmt nur Parameter und rechnet dann los
- schreibt die reinen Messdaten ohne jedwede Auswertung in die Konsole/Datei

Steuerungs-Prozess:
- GUI
- ruft den Benchmark-Prozess mit entsprechenden Parametern auf
- übernimmt die Ergebnisse, wertet sie aus und bereitet sie grafisch oder wie auch immer für den Benutzer auf
- kann in jeder beliebigen Sprache geschrieben sein.

Der Benchmark-Prozess wird bei einem CPU-Benchmark vermutlich nicht sehr groß. Bei dem Teil würd ich mich evtl. auch breitschlagen lassen dir zu helfen. Alles was mit Steuerung und GUI zu tun hat, ist aber ganz und garnicht mein Fall ;-)
 
Also jeder Prozessorkern braucht einen Thread, ebenso die GUI. GUI Maximum und Benchthreads AboveNormal würde ich mal sagen.
Wenn du wirklich Interesse und Lust hast mir einige Sachen zu zeigen und mir zu helfen, wäre das super!:)
Adde mich dann bei ICQ: 208011597.
 
Zuletzt bearbeitet:
Zurück
Oben