Unter x64_OS sollte man nicht IMMER Integer verwenden

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von Sicro »

Integer-Variablen unter einem 64Bit-OS immer zu bevorzugen ist nicht empfehlenswert, weil manchmal der Zeitgewinn zu gering ist, aber der Speicherverbrauch verdoppelt wird.

Code: Alles auswählen

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  CompilerError "Test-Code macht nur unter x64 Sinn!"
CompilerEndIf

CompilerIf #PB_Compiler_Debugger
  CompilerError "Debugger ausschalten!"
CompilerEndIf
; !!!!!!!!! Purifier ebenfalls ausschalten !!!!!!!!!

#Elements = 8000000

Dim LongArray.l(#Elements-1)
Dim IntegerArray.i(#Elements-1)

time = ElapsedMilliseconds()
For i = 0 To #Elements-1
  LongArray(i) = 1
Next
result1 = ElapsedMilliseconds() - time

time = ElapsedMilliseconds()
For i = 0 To #Elements-1
  IntegerArray(i) = 1
Next
result2 = ElapsedMilliseconds() - time

MessageRequester("", "LongArray: " + #CRLF$ +
                     ">> Zeit: "+Str(result1)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(LONG)*#Elements)+" Bytes" + #CRLF$ +
                     "IntegerArray: " + #CRLF$ +
                     ">> Zeit: "+Str(result2)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(INTEGER)*#Elements)+" Bytes")
LongArray:
>> Zeit: 29 ms
>> Speicher: 32000000 Bytes
IntegerArray:
>> Zeit: 31 ms
>> Speicher: 64000000 Bytes
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
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: Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von NicTheQuick »

Das ist jetzt natürlich nicht der beste Test um sowas zu messen. Vor allem nicht mit so wenig Bytes. Die sind ja alle zum großen Teil im Cache und dann wird nur eine 1 in ein Register kopiert. Das muss man schon mit etwas komplexeren Operationen machen.
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von Macros »

Hi,

Prinzipiell hast du natürlich recht, doch dein Code ist nicht ganz geeignet um den Unterschied aufzuzeigen.
Durch eine einzelne Schleifeniteration schwanken die Werte sehr, selbst wenn ich auf 80 Millionen Elemente erhöht habe, war mal Integer mal Long schneller.
Hier haben andere Effekte wohl Vorrang.

Außerdem liegt der große Vorteil von 64 Bit Variablen auf einem 64 Bit System vor allem bei Rechenoperationen.
Je mehr man mit den Variablen rechnet, umso eher sollte man 64 Bit benutzen. Bei normalen Variablen außerhalb von Arrays oder Listen sowieso.
Wen kümmert es, wenn das Programm 1KB weniger Speicher braucht. Zusätzlich passieren weniger wahrscheinlich Folgeprobleme wie:
Dateien über 2GB, Jahr 2038 Problem ...

Ich hab den Code etwas angepasst mit einer Multiplikation, weniger Linearen Zugriffen auf das Array und einem Mittelwert über ein paar Iterationen hinweg.
Ergebnis bei mir: Integer ist konstant ein winziges Stück flotter, und braucht eben deutlich mehr Speicher.
LongArray:
>> Zeit: 19.04 ms
IntegerArray:
>> Zeit: 18.1 ms

Code: Alles auswählen

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  CompilerError "Test-Code macht nur unter x64 Sinn!"
CompilerEndIf

; !!!!!!!!! Purifier ebenfalls ausschalten !!!!!!!!!

DisableDebugger
#Elemente = 800000
#iterations = 50

Dim LongArray.l(#Elemente-1)
Dim IntegerArray.i(#Elemente-1)

For i = 0 To #Elemente-1
  fill.i= Random(10000)
  LongArray(i) = fill
  IntegerArray(i)  = fill
Next

For a=1 To #iterations
  time = ElapsedMilliseconds()
  For i = 0 To #Elemente-1
    ;  Ein paar Sprünge in der Zugriffsposition und eine Multiplikation mit den Werten
    LongArray(i) = LongArray((i+100)%#Elemente) *LongArray((i+200)%#Elemente) 
  Next
  result1 = ElapsedMilliseconds() - time
  result1avg.d+result1/#iterations
Next

For a=1 To #iterations
  time = ElapsedMilliseconds()
  For i = 0 To #Elemente-1
    IntegerArray(i) = IntegerArray((i+100)%#Elemente) *IntegerArray((i+200)%#Elemente) 
  Next
  result2 = ElapsedMilliseconds() - time
  result2avg.d+result2/#iterations
Next

MessageRequester("", "LongArray: " + #CRLF$ +
                     ">> Zeit: "+StrD(result1avg)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(LONG)*#Elemente)+" Bytes" + #CRLF$ +
                     "IntegerArray: " + #CRLF$ +
                     ">> Zeit: "+StrD(result2avg)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(INTEGER)*#Elemente)+" Bytes")
Interessanterweise stellte ich bei weiteren Experimenten sogar einen gegenteiligen Effekt fest:
(Noch unberechenbarere Zugriffe, Addition und Modulo)
LongArray:
>> Zeit: 85.94 ms
IntegerArray:
>> Zeit: 93.44 ms

Code: Alles auswählen

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  CompilerError "Test-Code macht nur unter x64 Sinn!"
CompilerEndIf

; !!!!!!!!! Purifier ebenfalls ausschalten !!!!!!!!!



;DisableDebugger

Procedure KnuthShuffle(Array a(1))
   Protected i, last = ArraySize(a())
   For i = last To 1 Step -1
      Swap a(i), a(Random(i)) 
   Next 
EndProcedure
#Elemente = 800000
#iterations = 50

Dim LongArray.l(#Elemente-1)
Dim IntegerArray.i(#Elemente-1)

; fill array with index numbers, and shuffle it
For i = 0 To #Elemente-1
  IntegerArray(i)  = i
Next
KnuthShuffle(IntegerArray())
; copy to long array to have exactly the same operations later on
For i = 0 To #Elemente-1
  LongArray(i)  = IntegerArray(i)
Next

For a=1 To #iterations
  time = ElapsedMilliseconds()
  For i = 0 To #Elemente-1
    ;  Ein paar Sprünge in der Zugriffsposition und eine Addition+Division(Modulo) mit den Werten
    LongArray(i) = ( LongArray(LongArray(i))+LongArray(i))%#Elemente
  Next
  result1 = ElapsedMilliseconds() - time
  result1avg.d+result1/#iterations
Next

For a=1 To #iterations
  time = ElapsedMilliseconds()
  For i = 0 To #Elemente-1
    IntegerArray(i) =  ( IntegerArray(IntegerArray(i))+IntegerArray(i))%#Elemente
  Next
  result2 = ElapsedMilliseconds() - time
  result2avg.d+result2/#iterations
Next

MessageRequester("", "LongArray: " + #CRLF$ +
                     ">> Zeit: "+StrD(result1avg)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(LONG)*#Elemente)+" Bytes" + #CRLF$ +
                     "IntegerArray: " + #CRLF$ +
                     ">> Zeit: "+StrD(result2avg)+" ms" + #CRLF$ +
                     ">> Speicher: "+Str(SizeOf(INTEGER)*#Elemente)+" Bytes")
Hat jemand eine Idee, weshalb?
Meine einziger Erklärungsansatz:
Wegen der kleinen Größe kann der Prozessor mehr Elemente in seinen flotten Caches behalten.
Bild
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von GPI »

Man sollte sich auch allgemein überlegen, in wieweit man hier wirklich eine Optimierung machen sollte. Das mit den von dir angesprochenen Cache kann bspw. bewirken, das auf einer CPU long schneller ist, auf einer anderen Integer, weil halt die CPU mehr Cache hast. Es wurde mich auch nicht wundern, wenn Intel-Cpus und AMD-Cpus unterschiedliche Optimierungen benötigen und so weiter und so fort.

Eine Optimierung in diesen Bereich macht imo erst Sinn, wenn man eine feste Hardware hat - wie sie Konsolen (PS4, XBOX ONE) haben. Ansonsten schmeißt man unnötige Zeit raus.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Derren
Beiträge: 558
Registriert: 23.07.2011 02:08

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von Derren »

Speicherdiskussionen überlasse ich jetzt mal den Experten.
ABER: viele Win-API Funktionen erwarten Longs. Auch unter x64. Wenn man integer verwendet, kann es zu unerwarteten Ergebnissen führen. Das nur nebenbei ;)
Signatur und so
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Beitrag von mhs »

API Programmierung ist immer ein Sonderfall. In der MSDN ist das alles beschrieben.
In the Win64 model:

◦The Windows API follows the Uniform Data Model (UDM). UDM proposes to use identically named data types for both the Win32 and Win64 environments. Using this model, you can maintain a single source code development environment for both Win32 and Win64, provided no architecture-specific design features are implemented.


◦The size of int and long is 32 bits; the size of int64 (new type) and pointers is 64 bits.

Abstract types are identical for 32-bit and 64-bit environments, thus simplifying cross-compilation for both of them.


◦There are explicitly sized and scalable data types.
https://technet.microsoft.com/en-us/lib ... 96995.aspx
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Antworten