Seite 1 von 1

Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 20.02.2016 14:27
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

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 20.02.2016 18:19
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.

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 20.02.2016 18:26
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.

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 20.02.2016 21:16
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.

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 20.02.2016 23:56
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 ;)

Re: Unter x64_OS sollte man nicht IMMER Integer verwenden

Verfasst: 21.02.2016 10:40
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