StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Anfängerfragen zum Programmieren mit PureBasic.
hyperG
Beiträge: 23
Registriert: 28.06.2014 10:43

StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von hyperG »

Das Einlesen von 1GB funktioniert unter 10s,
ABER das Wandeln im Speicher per StrU(g_Array.q(k),#PB_Quad) dauert 3 min??

Code: Alles auswählen

For k=0 To ArraySize.i
    strSum.s =strSum.s+StrU(g_Array.q(k),#PB_Quad)
Next
Achtung: Quelle sind 64 Bit unsigned INT! Zwar können Variablen.q angeblich nur signed (mit Vorzeichen), aber per
StrU(g_Array.q(k),#PB_Quad) scheint die Wandlung auch mit Zahlen > 9223372036854775808 zu funktionieren.

ABER warum ist das so langsam??
Das geht doch per ASM unter 7s, ABER wie?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von NicTheQuick »

Bist du sicher, dass du das so machen willst? Einfach Zahlen aneinander hängen, die unterschiedliche Länge haben? Zurückrechnen lässt sich das so ja nicht mehr, weil es keine Trenner zwischen den Zahlen gibt.

Davon abgesehen, ist das Problem bei diesem Stück Code, dass pro Schleifendurchlauf der String immer ein Stückchen erweitert wird. Das heißt pro Schleifendurchlauf muss intern sozusagen ein 'ReAllocateMemory()' gemacht werden, damit der neue String in den Speicher passt. Da es irgendwann nicht mehr möglich ist den String an Ort und Stelle zu erweitern, muss er an eine andere Stelle im Speicher kopiert werden, wo er komplett rein passt. Und da das nun recht häufig passieren wird, ist das ganze so langsam. Die Lösung ist also folgende:
Man sollte schon von Anfang an genug Speicher allozieren und dann den String füllen. Das geht am besten dann mit 'CopyMemoryString()'. Also am Anfang weist man dem String z.B. 'Space(1000000000)' zu und füllt ihn dann von vorne. Oder man arbeitet gleich mit 'AllocateMemory()' und legt den Speicherbereich von Anfang an großzügig fest.
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von matbal »

Mir ist noch ein Grund eingefallen, warum das Anhängen von Strings in PB so ineffizient ist: Wenn Strings verlängert werden müssen, muß PB herausfinden, wo der String zu Ende ist. Da PB sich die Länge nicht merkt, wird jedes Mal das String-Ende-Zeichen neu gesucht. Demzufolge wird das Anhängen mit zunehmender String-Länge auch dann immer langsamer, wenn selten umkopiert werden muß.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von NicTheQuick »

Das stimmt so nicht ganz. Dafür muss PB nicht nach dem Nullbyte suchen.

Code: Alles auswählen

;Unicode deaktivieren!

s.s = "Hallo Welt."	;12 Zeichen inkl. Nullbyte

Debug MemorySize(@s) ;Trotzdem wurde mehr Speicher alloziert
Purebasic weiß ja wie groß der Speicherbereich ist, der gerade für den String benutzt wird. Und nur um den geht es. Es ist irrelevant genau zu wissen wo der String endet.
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von matbal »

NicTheQuick hat geschrieben:Purebasic weiß ja wie groß der Speicherbereich ist, der gerade für den String benutzt wird.
Das habe ich auch erst gedacht. Das kann aber so nicht stimmen. Wird ein Zeichen im String mit einem Null-Zeichen überschrieben, wird der String auch nur noch bis dahin gelesen. Das geht nur, wenn nach dem String-Ende gesucht wird.

Len() dauert bei langen Strings auch länger als bei kurzen. Das heißt für mich, auch da wird das Ende gesucht.

Übrigens dein Code erzeugt unter Windows den Fehler: Das angegebene "MemoryID" ist ungültig.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: StrU(g_Array.q(k),#PB_Quad) per ASM optimieren

Beitrag von NicTheQuick »

Achso, ich weiß jetzt wie du das meintest. Ich war gerade nur bei dem Thema, dass der Speicherbereich des Strings erweitert werden muss, wenn ein viel größerer dran gehängt werden soll. Aber natürlich muss man zum genauen Platzieren des anzuhängenden Strings auch wieder das Nullbyte suchen. Aber theoretisch könnte man danach ja auch von hinten suchen. Das ginge schneller, da man das echte Ende des Speicherbereichs ja kennt.

Unter Linux klappt das mit dem 'MemorySize()' scheinbar mit jeder Art Speicherbereiche, also auch mit Strings. Schade, dass es unter Windows nicht funktioniert. Ich bekomme hier jedenfalls eine Größe von 25 angezeigt.
Antworten