OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigung

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigung

Beitrag von juergenkulow »

Hallo PB-Universum,

Bei meinem Projekt dreht sich alles um schnelle und geschickte 3D-Stifteingabe mit bis zu 200 Eingabepunkten pro Sekunde.
Software Design Frage: Reicht die Ausgabegeschwindigkeit um jedes Frame ausgeben oder muß ein Fokus auf bestimmte Bildschirmbereiche gelegt werden?
Beim Test der Bildschirmausgabe habe ich einen starken Geschwindigkeitseinbruch bei OpenWindow, OpenWindowedScreen gegenüber OpenScreen.
Sind die Parameter für OpenWindow und OpenWindowedScreen richtig gesetzt um die Hardware-Beschleunigung zu erreichen?
Oder gibt es einen Weg die Adressen und die Schreibrechte vom Videospeicher nach OpenWindowedScreen zu bekommen?

Code: Alles auswählen

; Warum Geschwindigkeits-Test: Schreibe auf den Bildschirm-Buffer hier mit OpenWindowedScreen. Werden mehr als 59 fps erreicht? 
; Erstellt mit PureBasic  5.51 (x64) auf Wacom Cintiq Companion 2 2560x1440xR8G8B8A8@59 Windows 8.1 
; 78619 Zeilen/s 54 fps 98-102% CPU-Auslastung laut Resourcenmanager 
; bei reduzierter Auflösung 1920x1080 111380 Zeilen/s 77 fps  
; offen Stimmen die Aufrufe von OpenWindow und OpenWindowedScreen zur Hardware-Beschleunigung, da nur 21% der OpenScreen Leistung? (Win 8.1 und 7 Pro SP1 aber nicht Vista Home SP2)
; Oder gibt es einen Weg die Adressen und die Schreibrechte vom Videospeicher nach OpenWindowedScreen zu bekommen? 
EnableExplicit
Declare zeile(*wert) ; Procedure gibt Zeilen auf den Bildschirm aus.
Structure Bildschirmtyp : Name.s : Xpixel.w : Ypixel.w : Tiefe.w : fps.f : *Buffer : *Buffer2 : Pitch.l : Pixelformat.w : EndStructure
Dim Bildschirme.Bildschirmtyp(0) ; Im diesem Beispiel gibt es nur einen Bildschirm mit der Nummer 0 
InitSprite(): ExamineScreenModes() 
ExamineDesktops()
Bildschirme(0)\Xpixel=DesktopWidth(0) : Bildschirme(0)\Ypixel=DesktopHeight(0): Bildschirme(0)\fps=DesktopFrequency(0)
Define Fenster=OpenWindow(#PB_Any,
                          0,                       ; Anfängliche x Position des Fensters 
                          0,                       ; Anfängliche y Position des Fensters 
                          Bildschirme(0)\Xpixel ,  ; 2560 Pixel Breite 
                          Bildschirme(0)\Ypixel,   ; 1440 Pixel Höhe 
                          "Geschwindigkeits-TEST", ; Fenstername 
                          #PB_Window_BorderLess|#PB_Window_NoGadgets)   ; Flags keine Ränder - hier könnte etwas fehlen. 
                                                   ; kein ParentWindow
If 0=Fenster : MessageRequester("Fataler Fehler","OpenWindow fehlgeschlagen!") :End :EndIf 
If 0=OpenWindowedScreen(WindowID(Fenster), 
                        0,                      ; x Position 0 links
                        0,                      ; y Position 0 oben 
                        Bildschirme(0)\Xpixel,  ; 2560 Pixel Breite 
                        Bildschirme(0)\Ypixel,  ; 1440 Pixel Höhe
                        #False,                 ; keine Anpassung der Größe 
                        0,                      ; Stetuszeile  RightOffset
                        0,                      ; Statuszeile BottomOffset
                        #PB_Screen_SmartSynchronization) ; FlipModus  - Es scheint nur ein Videobuffer erstellt zu werden.
  MessageRequester("Fataler Fehler ","OpenWindowScreen fehlgeschlagen!")
  End 
EndIf

StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer()  ; Finde die Adresse des  Bildschirmm 
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() 
FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() :StopDrawing() 
Define j=0 
Define i 
Dim *Pufferfeld(Bildschirme(0)\Ypixel) 
*Pufferfeld(0)=AllocateMemory(Bildschirme(0)\Pitch * Bildschirme(0)\Ypixel)
Define *ptr=*Pufferfeld(0) 
For i=0 To Bildschirme(0)\Ypixel-1 ; Für Jede Zeile des *Pufferfeld
  *Pufferfeld(i) = *ptr
  *ptr+Bildschirme(0)\Pitch
  ; Füllte die Zeile mit grünen Punkten unterschiedlicher Helligkeit 
  For j=0 To Bildschirme(0)\Pitch-4 Step 4 :  PokeL(*Pufferfeld(i)+j,RGBA(0,Random(255),0,0)) : Next j 
Next i 
Define fertig=#False
Define fliptime=ElapsedMilliseconds()+16
Define Zeilen=0 
Define Cpus=CountCPUs(#PB_System_ProcessCPUs) :Dim thread(Cpus-1) 
thread(0)=CreateThread(@Zeile(),i) : ThreadPriority(thread(0),17) ; Prio 31 kaum Wirkung 
thread(1)=CreateThread(@Zeile(),i) : ThreadPriority(thread(1),17) ; 2. Thread bringt 10 zusätzliche fps 
; DisableDebugger ; bringt kaum etwas 
Define Startzeit=ElapsedMilliseconds()
Repeat
  Repeat
    Define Event = WindowEvent() ; Windows Event-Abfrage auf ALT-F4 
    If Event = #PB_Event_CloseWindow :  fertig=#True : EndIf
  Until Event = 0
  If ElapsedMilliseconds()>=fliptime ; Nach 16 ms wird ein FlipBuffers ausgelöst 
    FlipBuffers() 
    fliptime=ElapsedMilliseconds()+16 
  Else 
    Delay(1) ; Warte 1 Millisekunde - das Betriebssystems kann sich um die Threads und um anders kümmern 
  EndIf 
Until fertig=#True
EnableDebugger
For i=0 To Cpus-1 : If thread(i)<>0 : KillThread(thread(i)) : EndIf : Next i ; Threads beenden. 
Define Zeit.f=(ElapsedMilliseconds()-Startzeit)/1000 ; Messung ausgeben 
Define ZeilenProSekunde=Zeilen/Zeit
MessageRequester("Messung",
                 StrF(Zeit)+" s Zeilen:"+Str(Zeilen)+" Zeilen/s:"+Str(ZeilenProSekunde)+" fps:"+Str(ZeilenProSekunde/1440)+
                 " "+Bildschirme(0)\Xpixel+"x"+Bildschirme(0)\Ypixel+"@"+Bildschirme(0)\fps+#CRLF$+
                 Hex(Bildschirme(0)\Buffer)+" "+Hex(Bildschirme(0)\Buffer2))
End 

; Thread zur Ausgabe von Zeilen auf dem Bildschirm-Buffer 
Procedure zeile(*wert)
  Shared Zeilen
  Shared *Pufferfeld()
  Shared Bildschirme() 
  Define addzeilen=1  ; Es wird eine Bildschirmzeile ausgegeben 
  Define Laenge=Bildschirme(0)\Pitch*addzeilen ; Bildschirmzeilen in Bytes
  Repeat
    Define *Ziel= Bildschirme(0)\Buffer+Random( Bildschirme(0)\Ypixel-addzeilen) * Bildschirme(0)\Pitch ; zufällige Zeile
    Define *Quelle = *Pufferfeld(Random(Bildschirme(0)\Ypixel-addzeilen))                               ; zufällige Zeile 
    CopyMemory(*Quelle,*Ziel,Laenge) ; hier wird die CPU-Zeit verbraucht 
;    DisableDebugger:EnableASM:Mov rcx,Laenge : Sar rcx,3 : mov rsi, *Quelle : mov rdi, *Ziel : rep movsq :DisableASM:EnableDebugger
    ; x64 nötig - keine Wirkung 
    Zeilen+addzeilen ; Könnte ein Datarace sein? 
  ForEver
EndProcedure
; Geschichte 170101 Es sollte grünes Pixelrasuchen zu sehen sein, vergleichbar TV-Rauschen ohne Empfang. 
Zum Vergleich, hier ist der Code mit Openscreen mit den Blindflug-Problemen beim Testen:

Code: Alles auswählen

; Warum Geschwindigkeits-Test: Schreibe auf den Bildschirm-Buffer hier mit OpenScreen. Werden mehr als 59 fps erreicht? 
; Erstellt mit PureBasic  5.51 (x64) auf Wacom Cintiq Companion 2 2560x1440xR8G8B8A8@59 Windows 8.1 
; Zeilen/s:379696 fps:263 
EnableExplicit
Declare zeile(*wert) ; Procedure gibt Zeilen auf den Bildschirm aus.
Structure Bildschirmtyp : Name.s : Xpixel.w : Ypixel.w : Tiefe.w : fps.f : *Buffer : *Buffer2 : Pitch.l : Pixelformat.w : EndStructure
Dim Bildschirme.Bildschirmtyp(0) ; Im diesem Beispiel gibt es nur einen Bildschirm mit der Nummer 0 
InitSprite(): ExamineScreenModes() 
ExamineDesktops()
Bildschirme(0)\Xpixel=DesktopWidth(0) : Bildschirme(0)\Ypixel=DesktopHeight(0): Bildschirme(0)\fps=DesktopFrequency(0)
InitKeyboard() 

Define main_whnd=OpenScreen(Bildschirme(0)\Xpixel,
                            Bildschirme(0)\Ypixel,
                            32,   ; Bildschirme(0)\Tiefe,
                            "Geschwindigkeits-TEST",
                            #PB_Screen_SmartSynchronization)
StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer() ; Finde die Adresse des  Bildschirmm 
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() :FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() ; Finde die 2, Adresse des  Bildschirmm 

Define j=0 
Define i 
Dim *Pufferfeld(Bildschirme(0)\Ypixel) 
*Pufferfeld(0)=AllocateMemory(Bildschirme(0)\Pitch * Bildschirme(0)\Ypixel)
Define *ptr=*Pufferfeld(0) 
For i=0 To Bildschirme(0)\Ypixel-1 ; Für Jede Zeile des *Pufferfeld
  *Pufferfeld(i) = *ptr
  *ptr+Bildschirme(0)\Pitch
  ; Füllte die Zeile mit grünen Punkten unterschiedlicher Helligkeit 
  For j=0 To Bildschirme(0)\Pitch-4 Step 4 :  PokeL(*Pufferfeld(i)+j,RGBA(0,Random(255),0,0)) : Next j 
Next i 
Define fertig=#False
Define fliptime=ElapsedMilliseconds()+16
Define Zeilen=0 
Define Cpus=CountCPUs(#PB_System_ProcessCPUs) :Dim thread(Cpus-1) 
thread(0)=CreateThread(@Zeile(),i) : ThreadPriority(thread(0),17) ; alleine Zeilen/s:347098 fps:241
thread(1)=CreateThread(@Zeile(),i) : ThreadPriority(thread(1),17) 
; DisableDebugger ; bringt kaum etwas 
Define Startzeit=ElapsedMilliseconds()
Repeat
  ExamineKeyboard() ; Prüfe Tasteneingaben ESC-Taste beendet Programm 
Until KeyboardPushed(#PB_Key_Escape) ; 
EnableDebugger
For i=0 To Cpus-1 : If thread(i)<>0 : KillThread(thread(i)) : EndIf : Next i ; Threads beenden. 
CloseScreen()
Define Zeit.f=(ElapsedMilliseconds()-Startzeit)/1000 ; Messung ausgeben 
Define ZeilenProSekunde=Zeilen/Zeit
Debug StrF(Zeit)+" s Zeilen:"+Str(Zeilen)+" Zeilen/s:"+Str(ZeilenProSekunde)+" fps:"+Str(ZeilenProSekunde/1440)+
                 " "+Bildschirme(0)\Xpixel+"x"+Bildschirme(0)\Ypixel+"@"+Bildschirme(0)\fps+#CRLF$+
                 Hex(Bildschirme(0)\Buffer)+" "+Hex(Bildschirme(0)\Buffer2)
End 

; Thread zur Ausgabe von Zeilen auf dem Bildschirm-Buffer 
Procedure zeile(*wert)
  Shared Zeilen
  Shared *Pufferfeld()
  Shared Bildschirme() 
  Define addzeilen=1
  Define Laenge=Bildschirme(0)\Pitch*addzeilen
  Repeat
    Define *Ziel= Bildschirme(0)\Buffer+Random( Bildschirme(0)\Ypixel-addzeilen) * Bildschirme(0)\Pitch
    Define *Quelle = *Pufferfeld(Random(Bildschirme(0)\Ypixel-addzeilen))
    CopyMemory(*Quelle,*Ziel,Laenge)
;    EnableASM : Mov rcx,Laenge : Sar rcx,3 : mov rsi, *Quelle : mov rdi, *Ziel : rep movsq : DisableASM ; x64 nötig - kaum Wirkung 
    Zeilen+addzeilen 
  ForEver
EndProcedure
Bitte stelle Deine Fragen, denn den Erkenntnisapparat einschalten entscheidet über das einzig bekannte Leben im Universum.

Jürgen Kulow Wersten :D_üsseldorf NRW D Europa Erde Sonnensystem Lokale_Flocke Lokale_Blase Orion-Arm
Milchstraße Lokale_Gruppe Virgo-Superhaufen Laniakea Sichtbares_Universum
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von DarkSoul »

Sind die Parameter für OpenWindow und OpenWindowedScreen richtig gesetzt um die Hardware-Beschleunigung zu erreichen?
OpenScreen() / OpenWindowedScreen() öffnen einen Screen, der unter Windows mit DirectX funktioniert. Diese sind für gewöhnlich hardwarebeschleunigt - Aber nur solange das Rendering auch von der GPU aus geschieht und nicht von der CPU durch Kopieren von Speicherbereichen durchgeführt wird. Vernünftig installierte Grafiktreiber mal vorrausgesetzt :)

Code: Alles auswählen

CopyMemory(*Quelle,*Ziel,Laenge) ; hier wird die CPU-Zeit verbraucht 
Hat leider nicht viel mit Hardwarebeschleunigung zu tun. Das wird nämlich von der CPU erledigt und braucht seine Zeit.

Bei mir hat die Windowed-Version ziemlich genau 60FPS, während die Fullscreen-Version irgendwas bei 100FPS* hat. Wenn ich das richtig sehe, läuft die Fullscreen-Version gänzlich ohne Double-Buffering (wodurch die Begrenzung auf die maximale Bildschirmwiederholrate ausgehebelt wird).

Mein Bildschirm hat auch nur 60Hz, so dass die 100FPS ohnehin 40FPS zu viel wären. Die überzähligen Frames, die die Bildwiederholrate des Bildschirms übersteigen, kannst du bedenkenlos verwerfen. Meines Wissens bremst FlipBuffers() hier automatisch passend aus. Da das Fullscreenbeispiel diese Funktion nicht verwendet, funktioniert das natürlich nicht.
Software Design Frage: Reicht die Ausgabegeschwindigkeit um jedes Frame ausgeben oder muß ein Fokus auf bestimmte Bildschirmbereiche gelegt werden?
Mehr Frames zu erzeugen, als der Bildschirm darstellen kann, ist sinnfrei. 60FPS auf einem 60Hz-Monitor sind vollkommen ausreichend!
Bei meinem Projekt dreht sich alles um schnelle und geschickte 3D-Stifteingabe mit bis zu 200 Eingabepunkten pro Sekunde.
Hat nicht viel mit dem Problem zu tun. Die Geschwindigkeit der Eingabegeräte ist nicht zwingend auf die Geschwindigkeit der Ausgabe beschränkt. Nur wird der Bildschirm halt maximal so oft aktualisiert, wie er halt kann. Die Eingaben, die seit der letzten Bildschirmaktualisierung neu hinzugekommen sind, müssen halt ausgewertet und gesammelt werden und dann bei der nächsten Aktualisierung in einem Rutsch dargestellt werden.

Das Auge kann ohnehin nicht unendlich hohe Hz wahrnehmen. <)

* = Ich würde auf über 200FPS kommen, wenn die Endlosschleife mit ExamineKeyboard() wegen fehlendem Delay() nicht die kostbare Prozessorleistung verheizen würde.... :roll:

PS: Künstliches Festlegen der FlipBuffers()-Zeitabstände auf 16ms in der Windows-Version ist eine schlechte Idee, wenn dir FPS wichtig sind. Es gibt nämlich auch Monitore, die mehr als 60Hz verarbeiten können. :wink:

PPS: Gegen die gefürchteten Race-Conditions hilft übrigens der Einsatz von Mutex <) . Das wird hier nicht die Ursache sein, weil sich der durch das vorzeitige Abfragen der Zeilenzählvariable resultierende Fehler immer weniger ins Gewicht fällt, je länger die Messung läuft.
Bild
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von juergenkulow »

Hallo DarkSoul,
Vielen Dank für die ausführliche Antwort.
Ich hatte mir einen Codeschnipsel wie "Bildschirme(0)\Buffer= ... " oder da gibt es einen Parameter "xyz" der auf "$123A" gestellt wird oder EnableASM ..., erhoft.
Die Zielmaschine, Wacom Cintiq Companion 2 kann nur 59 oder 60 Hz.
Die GPU und CPU liegen hier auf einem Intel Haswell, auf dem einem Stück Silizium und werden vom selben "System Agenten" mit Speicher und Display verbunden.
Ich suche noch immer einen Code der bei OpenWindowedScreen genauso schnell auf den Bildschirm schreibt wie bei OpenScreen, wie dieser Code aussieht ist nicht entscheident.
Das Datarace in den Testprogrammen um die Leistungsfähigkeit zu zeigen, könnte durch ein Feld über alle Threads und Zusammenrechen am Ende behoben werden.

Hallo PB-Universum,
Wenn man x86-Code auf einer x64 Maschinen laufen läßt fehlt in Zeile 61 bzw. 43 fehlt ein .q : Define Startzeit.q=ElapsedMilliseconds()
Die ThreadPriority nach unten, und der 2. oder weiterer CreateThread können oder müssen an die Testmaschine angepaßt werden.
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von DarkSoul »

Ich verstehe irgendwie nur noch Bahnhof, weil du so unverständlich formulierst.

Was genau versprichst du dir von einer Geschwindigkeit zwischen 200 und 300Hz, wenn das Display nur 60Hz darstellen kann?

Das macht es am Ende keinen Unterschied, ob der Grafikspeicher 5000x, 200x oder auch nur 60x beschrieben wird, wenn ein 60Hz-Bildschirm angeschlossen wird. Einbußen gibt es erst, wenn diese 60Hz unterschritten werden.

Du arbeitest doch schon mit Threads:
- Einer berechnet die darzustellenden Zustände intern in höchstmöglicher Geschwindigkeit, ohne diese anzuzeigen
- Der andere rendert 60x pro Sekunde den momentane Zustand der Berechnungen aus dem ersten Thread (und lässt naturgemäß die "verpassten" Frames einfach aus)

Vorteile: Hat jemand eine Kartoffel als Grafikkarte, läuft die Berechnung trotzdem schnell und die Anzeige wird lediglich etwas ruckelig
Nachteile: 2 Threads, die Daten austauschen müssen (Gefahr von Race-Conditions und Einsatz von Mutex erforderlich. Letztere können zur Ausbremsung führen)

Geht sogar mit nur einem Thread:
- Nur jeden n-ten Durchlauf wird auch tatsächlich gerendert.
- n wird der Leistung entsprechend angepasst.

Vorteile: Leichtere Kommunikation, da nur eine Dauerschleife vorhanden ist.
Nachteile: n muss ermittelt werden und Spitzen in der Berechnung oder des Renderings führen evtl. zu Störungen.
Bild
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von juergenkulow »

Hallo DarkSoul,

ich bitte um Entschuldigung, bin im ICE mit 300 vorbei gefahren.
Meine Frage lautet:

Warum ist mein CopyMemory bei OpenWindowedScreen 5 mal langsamer als bei OpenScreen?

Hallo PB-Universum,

ich habe die beiden Prgramme verbessert und zu einem verbunden:

Code: Alles auswählen

; Warum Geschwindigkeits-Test: Schreibe 2x100.000 Bildschirmzeilen mit OpenScrenn OpenWindowedScreen. 
; Erstellt mit PureBasic  5.51 (x64) auf Wacom Cintiq Companion 2 2560x1440xR8G8B8A8@59 Windows 8.1 64 bit 
; Unter Vista 32 bit gibt es verschiedene Darstellungs und Mess-Probleme bei OpenWindowedScreen.  
CompilerIf 0=#PB_Compiler_Thread   : CompilerError "Bitte Compiler-Option Thread sicher einstellen" : CompilerEndIf
EnableExplicit
Declare zeile(Wert) ; Procedure gibt Zeilen auf den Bildschirm aus.
Declare.l LRGBA(rot.a,gruen.a,blau.a, alpha.a)
Structure Bildschirmtyp : Name.s : Xpixel.w : Ypixel.w : Tiefe.w : fps.f : *Buffer : *Buffer2 : Pitch.l : Pixelformat.w : EndStructure
Dim Bildschirme.Bildschirmtyp(0) ; Im diesem Beispiel gibt es nur einen Bildschirm mit der Nummer 0 
Dim CPUZeit(400000) 
InitSprite(): ExamineScreenModes() 
ExamineDesktops()
Bildschirme(0)\Xpixel=DesktopWidth(0) : Bildschirme(0)\Ypixel=DesktopHeight(0): Bildschirme(0)\fps=DesktopFrequency(0)
Define Fenster=OpenWindow(#PB_Any,
                          0,                       ; Anfängliche x Position des Fensters 
                          0,                       ; Anfängliche y Position des Fensters 
                          Bildschirme(0)\Xpixel ,  ; 2560 Pixel Breite 
                          Bildschirme(0)\Ypixel,   ; 1440 Pixel Höhe 
                          "Geschwindigkeits-TEST", ; Fenstername 
                          #PB_Window_BorderLess|#PB_Window_NoGadgets)   ; Flags keine Ränder - hier könnte etwas fehlen. 
                                                   ; kein ParentWindow
If 0=Fenster : MessageRequester("Fataler Fehler","OpenWindow fehlgeschlagen!") :End :EndIf 
Define main_whnd=OpenScreen(Bildschirme(0)\Xpixel, Bildschirme(0)\Ypixel, 32, "", #PB_Screen_SmartSynchronization) :CloseScreen()
If 0=OpenWindowedScreen(WindowID(Fenster), 
                        0,                      ; x Position 0 links
                        0,                      ; y Position 0 oben 
                        Bildschirme(0)\Xpixel,  ; 2560 Pixel Breite 
                        Bildschirme(0)\Ypixel,  ; 1440 Pixel Höhe
                        #False,                 ; keine Anpassung der Größe 
                        0,                      ; Stetuszeile  RightOffset
                        0,                      ; Statuszeile BottomOffset
                        #PB_Screen_SmartSynchronization) ; FlipModus  - Es scheint nur ein Videobuffer erstellt zu werden.
  MessageRequester("Fataler Fehler ","OpenWindowScreen fehlgeschlagen!")
  End 
EndIf
StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer()  ; Finde die Adresse des  Bildschirmms
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() 
FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() :StopDrawing() 
Define j=0 
Define i 
Dim *Pufferfeld(Bildschirme(0)\Ypixel) 
*Pufferfeld(0)=AllocateMemory(Bildschirme(0)\Pitch * Bildschirme(0)\Ypixel)
Define *ptr=*Pufferfeld(0) 
For i=0 To Bildschirme(0)\Ypixel-1 ; Für Jede Zeile des *Pufferfeld
  *Pufferfeld(i)  = *ptr
  *ptr +Bildschirme(0)\Pitch
  ; Füllte die Zeile mit Punkten unterschiedlicher Helligkeit 
  For j=0 To Bildschirme(0)\Pitch-4 Step 4 :  PokeL(*Pufferfeld(i)+j,LRGBA(Random(255),0,0,0)) : Next j ;rote Punkte
Next i 
Define Cpus=CountCPUs(#PB_System_ProcessCPUs) :Dim thread(Cpus-1) 
Define Zeilen=0
thread(0)=CreateThread(@Zeile(),0) : ThreadPriority(thread(0),17) : Zeilen+100000
thread(1)=CreateThread(@Zeile(),100000) : ThreadPriority(thread(1),17) : Zeilen+100000 
Define fertig=#False
Define Startzeit.q=ElapsedMilliseconds()
Repeat
  Repeat
    Define Event = WindowEvent() ; Windows Event-Abfrage 
  Until Event = 0
  FlipBuffers() 
  If 0=IsThread(thread(0)) : If 0=IsThread(thread(1)) : fertig=#True :EndIf : EndIf 
Until fertig=#True
Define Zeit.f=(ElapsedMilliseconds()-Startzeit)/1000 
Define ZeilenProSekunde=Zeilen/Zeit
Define fps=ZeilenProSekunde/Bildschirme(0)\Ypixel
CloseScreen()
Define main_whnd=OpenScreen(Bildschirme(0)\Xpixel,
                            Bildschirme(0)\Ypixel,
                            32,   ; Bildschirme(0)\Tiefe,
                            "Geschwindigkeits-TEST",
                            #PB_Screen_SmartSynchronization)
StartDrawing(ScreenOutput()) :
  Bildschirme(0)\Buffer = DrawingBuffer() ; Finde die Adresse des  Bildschirmm 
  Bildschirme(0)\Pitch=DrawingBufferPitch() 
  Bildschirme(0)\Pixelformat=DrawingBufferPixelFormat() 
StopDrawing() :FlipBuffers()
StartDrawing(ScreenOutput()) : Bildschirme(0)\Buffer2 = DrawingBuffer() ; Finde die 2, Adresse des  Bildschirmm 
Define Zeilen2=0
thread(0)=CreateThread(@Zeile(),200000) : ThreadPriority(thread(0),17) : Zeilen2+100000
thread(1)=CreateThread(@Zeile(),300000) : ThreadPriority(thread(1),17) : Zeilen2+100000 
fertig=#False
Define Startzeit2.q=ElapsedMilliseconds()
Repeat
  Delay(1) 
  If 0=IsThread(thread(0)) : If 0=IsThread(thread(1)) : fertig=#True :EndIf : EndIf 
Until fertig=#True
Define Zeit2.f=(ElapsedMilliseconds()-Startzeit2)/1000 
CloseScreen()
Define ZeilenProSekunde2=Zeilen2/Zeit2
Define fps2=ZeilenProSekunde2/Bildschirme(0)\Ypixel
OpenWindowedScreen(WindowID(Fenster),  0, 0, Bildschirme(0)\Xpixel, Bildschirme(0)\Ypixel, #False, 0, 0, #PB_Screen_SmartSynchronization)
Define s$
s$=Str(Bildschirme(0)\Xpixel)+"x"+Str(Bildschirme(0)\Ypixel)+"@"+Str(Bildschirme(0)\fps)+#CRLF$+
   "OpenWindowedScreen "+StrF(Zeit,3)+ " s Zeilen:"+Str(Zeilen)+ " Zeilen/s:"+Str(ZeilenProSekunde) +" fps:"+Str(fps) +#CRLF$+
   "OpenScreen "+        StrF(Zeit2,3)+" s Zeilen:"+Str(Zeilen2)+" Zeilen/s:"+Str(ZeilenProSekunde2)+" fps:"+Str(fps2)+#CRLF$ 
Define i 
s$+"Nr:    CPUZeit,       CPUZeit-Unterschied zwischen zwei CopyMemory in einem Thread:"+#CRLF$
For i=     2 To      5 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i= 59992 To  59995 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=100002 To 100005 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=159992 To 159995 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=200002 To 200005 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=259992 To 259995 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=300002 To 300005 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
For i=359992 To 359995 : s$+RSet(Str(i),6)+":"+Str(CPUZeit(i))+", "+Str(CPUZeit(i)-CPUZeit(i-1))+#CRLF$ : Next i 
Define Zaehler=0
For i=1      To  100000:
  If CPUZeit(i)>CPUZeit(i-1)+50000
    ; Debug RSet(Str(i),6)+":"+Str(CPUZeit(i))+" "+Str(CPUZeit(i)-CPUZeit(i-1)) 
    Zaehler+1 
  EndIf   
Next i 
s$+"OpenWindowedScreen Zähler über 50000:  "+Str(Zaehler)+#CRLF$
Zaehler=0
For i=200001 To  300000: 
  If CPUZeit(i)>CPUZeit(i-1)+50000 
    ;Debug RSet(Str(i),6)+":"+Str(CPUZeit(i))+" "+Str(CPUZeit(i)-CPUZeit(i-1)) 
    Zaehler+1 
  EndIf   
Next i 
s$+"OpenScreen Zähler:"+Str(Zaehler)+#CRLF$
;Debug s$
MessageRequester("Messung",s$)                
End 

Procedure.l LRGBA(rot.a,gruen.a,blau.a, alpha.a) : ProcedureReturn blau+gruen<<8+rot<<16+alpha<<24 : EndProcedure  

; Thread zur Ausgabe von Zeilen
Procedure zeile(Wert)
  Shared Zeilen
  Shared *Pufferfeld()
  Shared Bildschirme() 
  Shared CPUZeit() 
  Define addzeilen=1  ; Es wird eine Bildschirmzeile ausgegeben 
  Define Laenge=Bildschirme(0)\Pitch*addzeilen ; Bildschirmzeilen in Bytes
  Define i
  Define bis=Wert 
  DisableDebugger
  For i=wert To  wert+100000
    Define *Ziel= Bildschirme(0)\Buffer+Random( Bildschirme(0)\Ypixel-addzeilen) * Bildschirme(0)\Pitch ; zufällige Zeile
    Define *Quelle = *Pufferfeld(Random(Bildschirme(0)\Ypixel-addzeilen))                               ; zufällige Zeile 
    CopyMemory(*Quelle,*Ziel,Laenge)                                                                    ; hier wird die CPU-Zeit verbraucht 
    Define RegEAX.l
    Define RegEDX.l 
    EnableASM
    RDTSC     ; Schreibt CPU-Zeit in eax und edx Register in etwa 30 ns Schritten  
    Mov RegEAX,eax
    Mov RegEDX,edx 
    DisableASM
    CPUZeit(i)=RegEAX+RegEDX<<32 
  Next i   
  EndProcedure
; Geschichte 170101 Es sollte grünes Pixelrasuchen zu sehen sein, vergleichbar TV-Rauschen ohne Empfang. 
;   170102 Define Startzeit.q 32 bit Code auf 64 bit Maschine 
;   170113 Aus 2 Tests wurde 1 Test - Datarace beseitigt, Faktor 200% , feste 1440 in Messausgabe 
;   170117 CPU-Zeit Messung in Threads   
; Ausgabe 
; [11:57:45] 2560x1440@59
; OpenWindowedScreen 2.957 s Zeilen:200000 Zeilen/s:67636 fps:46
; OpenScreen 0.525 s Zeilen:200000 Zeilen/s:380952 fps:264
; Nr:    CPUZeit,       CPUZeit-Unterschied zwischen zwei CopyMemory in einem Thread:
;      2:1867498259600723, 28563
;      3:1867498259624216, 23493
;      4:1867498259651462, 27246
;      5:1867498259673533, 22071
;  59992:1867502261395718, 82353
;  59993:1867502261479499, 83781
;  59994:1867502261573975, 94476
;  59995:1867502261666738, 92763
; 100002:1867498259869203, 44742
; 100003:1867498259916633, 47430
; 100004:1867498259968077, 51444
; 100005:1867498260022305, 54228
; 159992:1867502225389637, 61074
; 159993:1867502225455994, 66357
; 159994:1867502225523005, 67011
; 159995:1867502225596376, 73371
; 200002:1867505784739914, 8475
; 200003:1867505784746340, 6426
; 200004:1867505784753660, 7320
; 200005:1867505784760971, 7311
; 259992:1867506551808990, 10062
; 259993:1867506551820132, 11142
; 259994:1867506551832678, 12546
; 259995:1867506551843067, 10389
; 300002:1867505784961025, 14682
; 300003:1867505784974489, 13464
; 300004:1867505784988265, 13776
; 300005:1867505785003148, 14883
; 359992:1867506559488243, 9093
; 359993:1867506559499559, 11316
; 359994:1867506559511334, 11775
; 359995:1867506559524228, 12894
; OpenWindowedScreen Zähler über 50000:  69532
; OpenScreen Zähler:145
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von DarkSoul »

- zweimal gepostet, einmal gelöscht -
Zuletzt geändert von DarkSoul am 30.01.2017 01:56, insgesamt 1-mal geändert.
Bild
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von DarkSoul »

Ich kann leider nicht mehr testen, da ich kürzlich vollständig auf Linux umgestiegen bin und kein Windows mehr zur Verfügung habe, da sich das letzte Exemplar inzwischen selbst ins Aus zerupdated hat. :wink:

Kann ja fast nur innerhalb von CopyMemory liegen. Vielleicht ist intern eine Mutex, die den Thread in die Warteschleife legt, bis er den Speicher beschreiben darf. So ne Situation wie:
Prog: *indenspeicherschreib*
System: Oh... gibt was neues *aktualisier* (Dein Thread wird hier pausiert, bis das fertig ist). Evtl. mal in einen "normalen" Speicherbereich kopieren.

Oder der Thread wird extrem ausgebremst bzw. oft pausiert. Evtl. mal statt CopyMemory was anderes "rechenintensives" tun und schauen, ob ds Problem noch besteht.
Bild
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von juergenkulow »

Hallo PB-Universum,

einige Messungen mit geänderten CopyMemory Parametern: (Zeile 146)

Code: Alles auswählen

CopyMemory(*Quelle,*Ziel,Laenge)    ; OpenWindowedScreen 2.957 s Zeilen:200000 Zeilen/s:67636 fps:46   Speicher auf Videospeicher
                                            ; OpenScreen 0.525 s Zeilen:200000 Zeilen/s:380952 fps:264
CopyMemory(*Quelle,*Quelle,Laenge)  ; OpenWindowedScreen 0.662 s Zeilen:200000 Zeilen/s:302115 fps:209 Speicher auf Speicher
                                             ;OpenScreen 0.431 s Zeilen:200000 Zeilen/s:464037 fps:322
CopyMemory(*Ziel,*Quelle,Laenge)   ; OpenWindowedScreen 13.682 s Zeilen:200000 Zeilen/s:14618 fps:10  Videospeicher auf Speicher
                                            ; OpenScreen 8.645 s Zeilen:200000 Zeilen/s:23135 fps:16
CopyMemory(*Ziel,*Ziel,Laenge)     ; OpenWindowedScreen 17.109 s Zeilen:200000 Zeilen/s:11690 fps:8   Videospeicher auf Videospeicher 
                                           ; OpenScreen 10.384 s Zeilen:200000 Zeilen/s:19260 fps:13
;                                     OpenWindowedScreen 0.011 s Zeilen:200000 Zeilen/s:18181818 fps:12626 Leerlauf 
;                                             OpenScreen 0.006 s Zeilen:200000 Zeilen/s:33333333 fps:23148
; Define j: For j=0 To Laenge : Next ;OpenWindowedScreen 2.389 s Zeilen:200000 Zeilen/s:83717 fps:58  Zählschleife 
;                                             OpenScreen 2.555 s Zeilen:200000 Zeilen/s:78278 fps:54
; EnableASM : Mov rcx,Laenge : Sar rcx,3 : mov rsi, *Quelle : mov rdi, *Ziel : rep movsq : DisableASM ; Wiederhole "Move Data from String to String" 64 bit
;                                     OpenWindowedScreen 3.263 s Zeilen:200000 Zeilen/s:61293 fps:42  ; Speicher auf Videospeicher
;                                             OpenScreen 0.545 s Zeilen:200000 Zeilen/s:366972 fps:254
Hallo DarkSoul,

schade. - Ohne Tests die Bremse bei OpenWindowedScreen unter Windows zu finden ist sehr, sehr schwer.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von #NULL »

ich sehe in dem code leider nicht durch, aber bist du sicher das dein graka treiber im windowed mode nicht einfach die fps beschränkt?
eventuell auch mal mit #PB_Screen_NoSynchronization und SetFrameRate(999999) versuchen.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: OpenWindow, OpenWindowedScreen Parameter HW-Beschleunigu

Beitrag von PMV »

#PB_Screen_SmartSynchronization funktioniert nicht im Fenstermodus.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten