Langsamer Code

Für allgemeine Fragen zur Programmierung mit PureBasic.
Peti
Beiträge: 7
Registriert: 25.04.2018 22:36

Langsamer Code

Beitrag von Peti »

Verzeihung wenn ich hier falsch bin. Habe PureBasic gekauft und mit der neusten Version 5.71 rumgespielt.
Dabei ist mir das selbe aufgefallen wie bei der älteren Demoversion. Nämlich das der Compiler sehr unterschiedlich schnellen Code erzeugt wie an folgenden Beispiel zu sehen ist.
(Und ja ich hab den Debugger ausgeschaltet)

Code: Alles auswählen

#ScreenWidth = 1920 
#ScreenHeight = 1080

If InitSprite() = 0 Or InitKeyboard() = 0
MessageRequester("Error", "DirectX is needed.",0)
EndIf

If OpenScreen(#ScreenWidth, #ScreenHeight, 32, "PB Plasma")

zeit=ElapsedMilliseconds()
RGB=255 <<24+255<<16+255<<8+0

If StartDrawing(ScreenOutput())
Buffer = DrawingBuffer() ; Get the start address of the screen buffer
Pitch = DrawingBufferPitch() ; Get the length (in byte) took by one horizontal line
PixelFormat = DrawingBufferPixelFormat() ; Get the pixel format. 

For d=1 To 100 ;100 x Screen mit Pixel beschreiben

For y = 0 To #ScreenHeight-1
For x = 0 To #ScreenWidth-1 ;Rechne alles in der innersten Klammer (auch y, nur Test)
;Var 1 Direkt in Klammer
;PokeL(buffer+Pitch*y+x*4,RGB) ;940 Millisec
;Var 2
;b=buffer+Pitch*y
;b=b+x*4
;PokeL(b,RGB) ;1920 Millisec 
;Var 3
;h=Pitch*y
;b=x*4
;hb=h+b
;PokeL(buffer+hb,RGB) ;1656 Millisec
;Var 4
b=buffer+pitch*y+x*4 
PokeL(b,RGB) ; 2625 Millisec
Next
Next

Next 
StopDrawing()
EndIf

ExamineKeyboard()
FlipBuffers()

Else
MessageRequester("Error","Can't open the screen !",0)
EndIf

MessageRequester("Zeitr",Str(ElapsedMilliseconds()-zeit),0)
Man sieht stark unterschiedliche Laufzeiten nur durch Unterteilung einer einfachen Rechnung.
Des weiteren ist mir aufgefallen das Divisionen 3 mal länger (3x!) brauchen als in C oder z.b. Blitzbasic. Auch Zuweisungen zu Integer-Feldern benötigen die doppelte Zeit als in Blitz3D. Bei Floating ist der Wert allerdings gleich. Bin ich der erste der das bemerkt ? Lösungen ? Bei den 3D Möglichkeiten scheint auch viel Luft nach oben zu sein zumal alle wichtigen Befehle zu fehlen scheinen. Ogre nun ja.... Ich weiss die Neuen motzen immer ;) Kann mir da trotzdem jemand helfen ?

Edit by NicTheQuick: Code-Tags gesetzt
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Langsamer Code

Beitrag von Mijikai »

Der Code wird so nichtmal mit PureBasic auf verschiednene PCs gleichschnell laufen.
Am besten alles was "verbuggt" sein soll isolieren und einzeln mit mehreren Durchläufen testen.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Langsamer Code

Beitrag von mk-soft »

1. Debugger ausschalten.
2. Nicht PokeL verwenden, sondern direkt schreiben.

Speicherschreibaufträge (LONG) = 1920 * 1080 * 100 = 207360000

bei mir etwa 1200 Millisekunden. Das heisst in 12 ms wurde der ganze Bild-speicher komplett beschrieben. 2073600 Long-Werte.

Langsam finde ich das nicht.

Code: Alles auswählen

#ScreenWidth = 1920 
#ScreenHeight = 1080

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "DirectX is needed.",0)
EndIf

Structure Pixel
  Pixel.l
EndStructure

If OpenScreen(#ScreenWidth, #ScreenHeight, 32, "PB Plasma")
  
  zeit=ElapsedMilliseconds()
  RGB=255 <<24+255<<16+255<<8+0
  
  If StartDrawing(ScreenOutput())
    Buffer = DrawingBuffer() ; Get the start address of the screen buffer
    Pitch = DrawingBufferPitch() ; Get the length (in byte) took by one horizontal line
    PixelFormat = DrawingBufferPixelFormat() ; Get the pixel format. 
    
    For d=1 To 100 ;100 x Screen mit Pixel beschreiben
      
      For y = 0 To #ScreenHeight-1
        
        *Line.Pixel = Buffer+Pitch*y
        
        For x = 0 To #ScreenWidth-1
          *Line\Pixel = rgb
          *Line+4
        Next
      Next
       
    Next 
    StopDrawing()
  EndIf
  
  ExamineKeyboard()
    
  FlipBuffers()
  
  CloseScreen()
Else
  MessageRequester("Error","Can't open the screen !",0)
EndIf

MessageRequester("Zeitr",Str(ElapsedMilliseconds()-zeit),0)

Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Langsamer Code

Beitrag von Kiffi »

wo soll da jetzt der Bug sein?
Hygge
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Langsamer Code

Beitrag von NicTheQuick »

Da ist kein Bug. Deswegen steht es jetzt in Allgemein. :allright:
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Langsamer Code

Beitrag von STARGÅTE »

>> "Man sieht stark unterschiedliche Laufzeiten nur durch Unterteilung einer einfachen Rechnung."
Das ist einfach zu erklären.
Im ersten Fall wird kein "weiterer" Schreibvorgang auf eine Variable benötigt, die Rechung erfolgt komplett in den general purpose registers.
Im 2. und 3. Fall müssen die Zwischenvariablen sowohl geschrieben als auch gelesen werden. Der PB Compiler optimiert hier nicht, indem er erkennt, dass du z.b. Variable "b" gleich weiter verwendest und führt somit: "MOV qword [v_b],r15" und danach MOV rcx,qword [v_b] aus.
Warum bei dir der 4. Fall am langsamsten ist, kann ich nicht begründen, bei mir ist er schneller als Fall 1 und 2, was logisch wäre, da ich nur eine Hilfsvariable habe.

>> "Des weiteren ist mir aufgefallen das Divisionen 3 mal länger (3x!) brauchen als in C oder z.b. Blitzbasic."
PureBasic verwendet für die 3er Division auch "nur" den "IDIV" Befehl, allerdings kann man die 3er Division (oder auch andere) durchaus schneller ausführen, wenn man zuerst das Inverse berechnet und dann Multipliziert. Das hängt aber sehr stark von der jeweiligen CPU Architektur ab!

Es mag sein das der PB-Compiler wenig oder kaum optimiert. Allerdings ist er dafür halt ein Single-Pass-Compiler und wie ich finde ein sehr schneller. Außerdem hast du jeder Zeit die Möglichkeit, Zeitkritischen Code direkt in ASM zu schreiben. Wobei ich den Screen trotzdem nicht mit Hilfe der armen CPU zupixeln würde. Das sollte man Shadern für die Grafikkarte überlassen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Peti
Beiträge: 7
Registriert: 25.04.2018 22:36

Re: Langsamer Code

Beitrag von Peti »

Also mal vielen Dank für die Erläuterungen. Natürlich ist es kein Bug wenn ein Befehl 3 mal langsamer ist als in anderen Basics oder Feld-Zuweisungen in Integer halb so schnell. Und natürlich kann man es mit Assembler lösen aber hätte schon erwartet das solch einfache Sachen in einem Basic, dass es schon einige Zeit gibt besser optimiert sind. Genauso diese kleinen unnötigen Dinge wie Proceduren am Ende, wäre keine grosse Sache dies mit einem einfachen Skript zu beheben. Oder Print Zahlen und Text anzeigen zu lassen oder Loadimage den Decoder an Hand der Endung selber wählt. Genauso InitSprite() InitKeyboard() und Prüfung könnte man in einen Befehl packen (z.B. Open3D) usw. Hab erst ein paar Stunden rumgespielt aber mir fehlt ein bisschen die liebe zum Detail. Ausserdem muss man in PB viel schreiben und die Schlüsselworte sind teilweise extrem lang. Mal sehen was ich damit mache. Auf jeden Fall nochmals vielen Dank.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Langsamer Code

Beitrag von STARGÅTE »

/:-> Ähm, warum hattest du dich noch mal für den Kauf von PureBasic entschieden?

Da du wieder einige sehr präzise Beispiele aufzählst, möchte ich diese auch noch mal (aus Sicht der/eines Entwickler) Kommentieren:

>> "aber hätte schon erwartet das solch einfache Sachen in einem Basic, dass es schon einige Zeit gibt besser optimiert sind."
"optimiert" ist ein Begriff der noch ein Bezug verlangt. Natürlich kann man jede mögliche Division in der Zeit optimieren indem man sie einfach vorher ausrechnet und in einer Art Hash-Tabelle nachschlägt, oder besondere Formeln verwendet. Zum Teil wird das in PureBasic schon gemacht: ASM - fyl2x langsammer als Log10 oder Log ? (nur alsBeispiel)
Aus sieht der Entwickler besteht/bestand aber scheinbar keine Notwendigkeit dafür, alles auf Ausführungszeit zu optimieren, dafür aber an andere Stelle mehr externe Libraries, Speicher oder sonst was zu benötigen.

>> "Genauso diese kleinen unnötigen Dinge wie Proceduren am Ende, wäre keine grosse Sache dies mit einem einfachen Skript zu beheben."
Was meinst du damit?

>> "Oder Print Zahlen und Text anzeigen zu lassen"
Ja, kann man in betracht ziehen.

>> "oder Loadimage den Decoder an Hand der Endung selber wählt."
Das macht LoadImage doch, soweit ich weiß, sogar anhand des Dateiinhalts! Nur ist zur zeit der Kompilierung nicht bekannt, welche Decoder benötigt werden, und es ist einem Benutzer wie uns nicht zuzumuten, die EXE immer mit allen Decodern zuzumüllen, also entscheidet dieser selbst welche eingebaut werden sollen.

>> "Genauso InitSprite() InitKeyboard() und Prüfung könnte man in einen Befehl packen (z.B. Open3D) usw."
S.o. dann wäre in vielen Fällen immer "etwas zu viel" in der EXE, und da es ein Single-Pass-Compiler ist, kann es auch nachträglich nicht wieder entfernt werden, wenn Bibliotheken gar nicht verwendet werden.

>> "Außerdem muss man in PB viel schreiben und die Schlüsselworte sind teilweise extrem lang."
Dann wäre wohl die Godot Engine ehr was für dich? Wobei ich wie gesagt nicht weiß, für welches Zweck du PureBasic gekauft hast?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Langsamer Code

Beitrag von RSBasic »

Hallo Peti
Peti hat geschrieben:Ausserdem muss man in PB viel schreiben und die Schlüsselworte sind teilweise extrem lang.
Dank Autovervollständigungsfunktion musst du nicht komplett ausschreiben.
Ansonsten kannst du auch ein Macro schreiben, z.B.:

Code: Alles auswählen

Macro EndProc
  EndProcedure
EndMacro
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Antworten