|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Eternal_pain
Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 06.10.2011, 12:26 Titel: Programmausführung rapide gesunken?! |
|
|
Da ich von ausgehe das es nichts mit FreeBASIC direkt oder OpenGL zu tun hat, mir der fehler jedoch damit erst aufgefallen ist...
öffter habe ich das Problem das eine Schleife wesentlich langsamer durchläuft als es 'normal' sein sollte:
so habe ich mit diesen paar zeilen zB nur ~65FPS angezeigt wo es eigentlich ~500-~800 oder mehr sein sollten...
Code: |
Dim FPS as Integer
Dim FPS_T as Double=Timer+1
do
if multikey(&h01) then exit do
FPS+=1
If Timer>=FPS_T Then
?FPS
FPS_T=Timer+1
FPS=0
End If
sleep 1
loop
|
hat evtl jemand ahnung woran das liegen könnte oder was dagegen zu tun ist? _________________
|
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 06.10.2011, 12:43 Titel: |
|
|
Das liegt an Sleep.
Sleep mit 1 heist nicht zwangsweise, das er nur 1ms wartet, sondern durchaus länger als man meint. Das ganze ist auch extrem OS abhängig.
Wen du eine Beschleunigung erhalten willst, kannst du unterschiedliche Varianten anwenden um dies zu erreichen.
1.
Du packst das sleep in die Print ebene mit rein
Code: |
Dim FPS as UInteger
Dim FPS_T as Double
Do
if multikey(&h01) then exit do
FPS += 1
If Timer() >= FPS_T Then
print FPS
FPS_T = Timer + 1
FPS = 0
sleep 1, 1
End If
loop
|
(ca. 2,7 MFpS)
2.
Du nutzt eine 2. timer prüfung:
Code: |
Dim FPS as UInteger
Dim FPS_T as Double
Dim FPS_T2 as Double
Do
if multikey(&h01) then exit do
FPS += 1
If Timer() >= FPS_T Then
print FPS
FPS_T = Timer + 1
FPS = 0
End If
If Timer() >= FPS_T2 Then
Sleep 1, 1
FPS_T2 = Timer + 0.01
End If
loop
|
(bei 10ms ca. 1 MFpS)
3.
Du nutzt eine Zählervariable um die FpS per Count zu multiplizieren.
Code: |
Dim FPS as UInteger
Dim FPS_T as Double
Dim FPS_C as UInteger
Do
if multikey(&h01) then exit do
FPS += 1
If Timer() >= FPS_T Then
print FPS
FPS_T = Timer + 1
FPS = 0
End If
FPS_C += 1
If FPS_C >= 20 Then
Sleep 1, 1
FPS_C = 0
End If
loop
|
Bei 10 = FPS * 10 -> 5000 (unter linux hab ich 250 FpS mit Sleep 1)
usw.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
Eternal_pain
Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 06.10.2011, 12:59 Titel: |
|
|
Danke,
mir ging es dabei nicht nur auf Geschwindigkeit wobei ich 65FPS extrem wenig finde, sondern auch auf reduzierung der CPU auslastung...
Wundere mich allerdings, warum es manchmal 'normal' funktioniert und dann wieder nicht... heute morgen funktionierte noch alles normal vermutlich um die 500FPS, allerdings nicht gemessen zu der zeit, fiel mir leider erst auf als ein beispiel auf einmal in zeitlupe zu laufen schien und suchte den fehler dann stundenlang in neu hinzugefügten funktionen :/
die 2. Variante mit einem extra timer finde ich ganz gut, da kann man etwas variieren um evtl. einen optimalen schnitt zu finden
letztenendes würden 65FPS ja ausreichen, allerdings in einer schleife wo sogut wie nichts passiert erscheint es mir etwas wenig... _________________
|
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 06.10.2011, 13:15 Titel: |
|
|
wenn du eine optimale beschleunigugn haben willst, dann hau das sleep raus, oder nutze 2 threads. einem in welchem du die reine berecnung ausführst, und einen der für die grafische anzeige zuständig ist. Im grafik-thread solltest du allerdings vorzugsweise mit einen Backbuffer arbeiten. hast du keinen zur verfügung, dann erzeuge ein img, und schreibt dort rein, bevor du mit screenlock sperrst und put'est. das erhöht nochmal den speed, da beim zeichnen bzw. unlocken kein sync auf den monitor erfolgt.
falls du mit threads arbeiten solltest, dann empfehle ich dir mal dies zu lesen: http://www.freebasic-portal.de/tutorials/threading-optimierung-teil-2-75.html
Das mit dem Sleep ist, wie schon gesagt, sehr OS abhängig. Es kann gut sein, das nach nem neustart dein OS noch nicht so "zugemüllt" ist, und wenig programme im hintergrund arbeiten, bzw. das ram noch aufgeräumt ist und wenig geswapt werden muss.
nach längerem betrieb und längerer arbeit am sys kann es allerdings zu höheren SWAP aktionen kommen. Soetwas lässt sich jedoch unheimlich schwer definieren, wann welche faktoren dein programm beeinflussen, wenn mit sleep gearbeitet wird.
Hier spielen auch Threadwechsel und prioritätsfaktoren für threads eine rolle, sowie die handhabe von windows / linux mit dem thread der app's. Wie genau und wann welche algorythemn zum wechsel angewendet werden, usw usw usw.
willst du das maximum herausholen musst du auf sleep gänzlich verzichten.
Zwar erhöhst du damit die CPU auslastugn, allerdigns ist die CPU auch dafür da, um auch mal ihre volle leistung für eine rechenaufgabe bereit zu stellen. Und wenn dein Programm dies benötigt, dann nutze sie.
Andernfalls bleibt dir nur die möglichkeit sleep zu "minimieren" durch eine von vielen varianten um sleep "verspätet" oder "zyklisch" aufzurufen und damit entsprechend linear oder logarythmisch mehr zeit fürs berechnen heraus zu holen.
Bedenke jedoch, das derartige "optimierungen" im endeffekt wieder auf die CPU lasten. Je länger das sleep ausbleibt, desto höher wird deine CPU belastung. Irgend wann hast du vollast und nur gelegentliche einbrüche durch das sleep.
Das optimimum zu finden ist hier wohl dann die Herausvorderung.
Aber wie schon gesagt, überlege dir, wie wichtig dir die FPS sind. wenn es unumgänglich wird, solltest du eifnach die volle leistung nutzen.
MfG
TPM
PS: eine weitere variante ist z.B. da ausmessen der FPS pro sleep zyklus. Ist dir das FPS verhältniss zu langsam, dann nutze den wert um per algorythmus die wartezeit für das sleep neu zu errechnen. Dadurch hast du quasi eine autonome sich dynamisch anpassende FpS optimierung geschrieben.
Wird dein FPS zu low, regelt der code die wartezeit für das nächste sleep nach oben. ist das fps zu hoch regelt es die wartezeit herunter. Dadurch solltest du immer eine konstante FpS zahl haben
um "schwingungen" zu vermeiden 30 -> 100 -> 30 -> 100 FPS, könntest du einen sogenannten PD oder PDI Regler verwenden, welcher das schwingen weg kompensiert. _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 06.10.2011, 15:04 Titel: |
|
|
Eternal_pain hat Folgendes geschrieben: | Wundere mich allerdings, warum es manchmal 'normal' funktioniert und dann wieder nicht... heute morgen funktionierte noch alles normal vermutlich um die 500FPS, allerdings nicht gemessen zu der zeit, fiel mir leider erst auf als ein beispiel auf einmal in zeitlupe zu laufen schien und suchte den fehler dann stundenlang in neu hinzugefügten funktionen :/
| Die Timer-Präzision kann unter anderem von laufenden Programmen gesetzt werden, ich habe z.B. vor Jahren in einem meiner Programme eine andere Performance gehabt wenn im Hintergrund Winamp lief. Von daher: Auf Sleep als präzisen Zeitgeber kann und darf man sich nicht verlassen. Stattdessen muss man schauen, wie viele Frames in der Zwischenzeit wirklich hätten gerendert werden sollen und das dann soweit nachholen. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 06.10.2011, 17:59 Titel: |
|
|
In der MSDN steht auch recht deutlich, dass bei sleep Werte kleiner als ca. 18 ms unzuverlässig und sleep allgemein ungenau ist |
|
Nach oben |
|
|
Eternal_pain
Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 06.10.2011, 18:44 Titel: |
|
|
Nuja, das sleep nicht sehr genau ist, war mir ja eigentlich bekannt, hat auch nicht weiter gestört, das obligatorische 'sleep 1' sollte einfach nur zur reduzierung der CPU last dienen.
Bisher hatte ich eigentlich nie derart grosse Einbrüche in der Geschwindigkeit festgestellt gehabt, erst seit ich mit OpenGL 'experimentiere' weshalb ich es zuerst darauf zurückgeführt hatte...
bei meinen 'tests' benutze ich sleep derzeit meistens zum 'drosseln' der geschwindigkeit um das geschehen im detail zu 'beobachten'
Wie gesagt sind mir 'derzeit' die FPS ansich nicht so wichtig, denke das in einem 'fertigen' Programm ~65 Frames durchaus ausreichend sind, diese sollte dann aber auch zuverlässig und konstant sein...
Wie gesagt, wunderte mich nur das es so extreme abweichungen mit sleep geben kann die mir bisher noch nicht aufgefallen waren... _________________
|
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 06.10.2011, 19:19 Titel: |
|
|
Mach einfach VSync an, dann hast du konstant 60/75 FPS, solange weder CPU noch GPU limitieren. Und das tun sie so schnell nicht... |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|