Seite 1 von 1

Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 01:04
von pp516
Um ein schnelles Rechenergebnis zu erhalten, möchte ich eine großes Array zum Sortieren usw. einsetzen.
Leider läßt sich das Array nicht anlegen. Ich habe den Code auf das Wesentliche reduziert:

Code: Alles auswählen

#INTEGER_HALBE =  1073741803; Halber signed Integer Maximalwert, abgerundet
Dim KompVersionen.q(#INTEGER_HALBE / 8) 
For xQ.q = 0 To (#INTEGER_HALBE / 8)
  KompVersionen.q(xQ) = xQ
Next xQ
Debug ( "Integer halbe Bytes gefuellt !" );   ist OK

FreeArray(KompVersionen.q())

#INTEGER_VOLL =  2147483647; signed Integer Maximalwert
Dim KompVersionen.q(#INTEGER_VOLL / 8) 
For xQ.q = 0 To (#INTEGER_VOLL / 8)
  KompVersionen.q(xQ) = xQ;   Ungültiger Speicherzugriff. (Lesefehler an der Adresse 18446744073709551600)
Next xQ
Debug ( "Integer Bytes gefuellt !" )
Das Programm wird mit Lesefehler angehalten.
Eigentlich wollte ich ein 4 GByte Array anlegen. Warum schaffe ich das nicht?

Rahmebedingungen:
Windows 7 X64
16 GByte HSP
Laut Windows Task Manager 9534 MByte frei
PureBasic 4.60 (X64)
Startmeldung im Editor: Executable-Typ Windows - x64 (64bit)
Tritt sowohl bei Compilieren mit Debugger als auch bei Executable auf.

Hat jemand eine Idee, was ich falsch mache ?

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 01:34
von STARGÅTE
Weil du unter Windows nicht den nötigen Speicher für deinen Prozess reserviert bekommst.
(Einschränkung unter Windows)

Mit ArraySize() kannst du prüfen ob das Array erfolgreich angelegt wurde, damit es nicht zum Fehler kommt.

Code: Alles auswählen

Dim ZuGross.q(10000000000)
If ArraySize(ZuGross()) = -1
	Debug "Array wurde nicht angelegt!"
EndIf
Unabhängig davon, ist dein Code natürlich totaler quark.
Wozu legst du ein Array an, wo jeder Index mit der IndexNummer initiallisiert wird?

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 01:53
von NicTheQuick
STARGÅTE hat geschrieben:Weil du unter Windows nicht den nötigen Speicher für deinen Prozess reserviert bekommst.
(Einschränkung unter Windows)
Bist du sicher? Auch bei x64? und was macht man dann, wenn man mal mehr Speicher braucht?

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 02:23
von pp516
STARGÅTE hat geschrieben:Unabhängig davon, ist dein Code natürlich totaler quark.
Wozu legst du ein Array an, wo jeder Index mit der IndexNummer initiallisiert wird?
:lol: Richtig erkannt ! Ich wollte in der Abstraktion meines Problems nicht meinen ganzen Code aufführen.
STARGÅTE hat geschrieben:Weil du unter Windows nicht den nötigen Speicher für deinen Prozess reserviert bekommst.
(Einschränkung unter Windows)
Wenn das stimmt, ist Windows 7 X64 für mich als Betriebssystem nicht geeignet :cry: Dann muss ich mal wieder bei UNIX vorbeischauen. Da habe ich mit X64 aber auch keine Erfahrungen.

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 02:26
von NicTheQuick
pp516 hat geschrieben:Da habe ich mit X64 aber auch keine Erfahrungen.
Das ist nicht anders wie x86, bloß kannst du eben mehr Speicher ansprechen und auch benutzen. Auf unserem Server hier an der Uni mit 1 TB RAM kann man aus C heraus ganz einfach 50 GB allozieren. Mehr kann ich nicht mit Sicherheit sagen, weil ich mehr noch nicht gebraucht hatte. :wink:

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 06:09
von Danilo

Code: Alles auswählen

#INTEGER_HALBE =  1073741803; Halber signed Integer Maximalwert, abgerundet
Dim KompVersionen.q(#INTEGER_HALBE / 8) 
Debug ArraySize(KompVersionen())
    ;For xQ.q = 0 To (#INTEGER_HALBE / 8)
    ;  KompVersionen.q(xQ) = xQ
    ;Next xQ
Debug ( "Integer halbe Bytes gefuellt !" );   ist OK

FreeArray(KompVersionen.q())

#INTEGER_VOLL =  2147483647; signed Integer Maximalwert
Dim KompVersionen.q(#INTEGER_VOLL / 8)
Debug ArraySize(KompVersionen())
    ;For xQ.q = 0 To (#INTEGER_VOLL / 8)
    ;  KompVersionen.q(xQ) = xQ;   Ungültiger Speicherzugriff. (Lesefehler an der Adresse 18446744073709551600)
    ;Next xQ
Debug ( "Integer Bytes gefuellt !" )
Das zweite ArraySize() gibt -1 zurück!

Nimmt man stattdessen ReDim(), funktioniert es:

Code: Alles auswählen

#INTEGER_HALBE =  1073741803; Halber signed Integer Maximalwert, abgerundet
Dim KompVersionen.q(#INTEGER_HALBE / 8) 
Debug ArraySize(KompVersionen())
    ;For xQ.q = 0 To (#INTEGER_HALBE / 8)
    ;  KompVersionen.q(xQ) = xQ
    ;Next xQ
Debug ( "Integer halbe Bytes gefuellt !" );   ist OK

;FreeArray(KompVersionen.q())

#INTEGER_VOLL =  2147483647; signed Integer Maximalwert
ReDim KompVersionen.q(#INTEGER_VOLL / 8)
Debug ArraySize(KompVersionen())
    ;For xQ.q = 0 To (#INTEGER_VOLL / 8)
    ;  KompVersionen.q(xQ) = xQ;   Ungültiger Speicherzugriff. (Lesefehler an der Adresse 18446744073709551600)
    ;Next xQ
Debug ( "Integer Bytes gefuellt !" )
Das geht hier auch:

Code: Alles auswählen

#INTEGER_VOLL =  2147483647-56 ; signed Integer Maximalwert
Dim KompVersionen.q(#INTEGER_VOLL / 8)
Debug ArraySize(KompVersionen())
Nimmt man -55 kommt -1 raus.

Mit ReDim dagegen geht es mit dem vollen Wert:

Code: Alles auswählen

#INTEGER_VOLL =  2147483647; signed Integer Maximalwert
Dim KompVersionen.q(1)
ReDim KompVersionen.q(#INTEGER_VOLL / 8)
Debug ArraySize(KompVersionen())
Aber schau mal das an:

Code: Alles auswählen

#INTEGER_VOLL =  2147483647 ; signed Integer Maximum

Debug #INTEGER_VOLL / 16
Debug #INTEGER_VOLL / 8
Debug #INTEGER_VOLL / 4
Debug #INTEGER_VOLL / 2
Debug #INTEGER_VOLL / 1

Debug "---"

Dim KompVersionen.q(#INTEGER_VOLL / 16)
Debug ArraySize(KompVersionen())        ; 134217727

FreeArray(KompVersionen())

Dim KompVersionen.q(#INTEGER_VOLL / 8)
Debug ArraySize(KompVersionen())        ; -1

FreeArray(KompVersionen())

Dim KompVersionen.q(#INTEGER_VOLL / 4)
Debug ArraySize(KompVersionen())        ; 536870911

FreeArray(KompVersionen())

Dim KompVersionen.q(#INTEGER_VOLL / 2)
Debug ArraySize(KompVersionen())        ; 1073741823

FreeArray(KompVersionen())

Dim KompVersionen.q(#INTEGER_VOLL - 7)  ; remove the -7 = crash
Debug ArraySize(KompVersionen())        ; -1

FreeArray(KompVersionen())
Habe es auch mal im engl. Forum als Frage in den Raum gestellt: Windows PB 4.60 x64 - Dim strangeness

Re: Array - Größe stark eingeschränkt ?

Verfasst: 05.02.2012 23:42
von pp516
@Danilo: Da bin ich ja gespannt, was dabei rauskommt.
Mein Problem konnte ich dank Deines Tipps mal befriedigend umgehen.
Ich machs jetzt so und verwende 8 GByte:

Code: Alles auswählen

#EINGBYTE =      1073741824
#VIERGBYTE =     4294967296
#ACHTGBYTE =     8589934592

Dim KompVersionen.q(#EINGBYTE / 8) 
Array_Laenge.q = ArraySize(KompVersionen())
Debug (Str(#EINGBYTE / 8) + ": Array - Laenge = " + Str(Array_Laenge.q))     

FreeArray(KompVersionen.q())

Dim KompVersionen.q(#VIERGBYTE / 8) 
Array_Laenge.q = ArraySize(KompVersionen())
Debug (Str(#VIERGBYTE / 8) + ": Array - Laenge = " + Str(Array_Laenge.q))     

FreeArray(KompVersionen.q())

Dim KompVersionen.q(1) 
ReDim KompVersionen.q(#ACHTGBYTE / 8) 
Array_Laenge.q = ArraySize(KompVersionen())
Debug (Str(#ACHTGBYTE / 8) + ": Array - Laenge = " + Str(Array_Laenge.q))     
For xQ.q = 0 To (#ACHTGBYTE / 8)
  KompVersionen.q(xQ) = xQ; 
Next xQ
Debug ( "8 GByte beschrieben ! ( " + Str( (KompVersionen.q(xQ-1)*8) ) + " Byte )")


; Debugger - Ausgabe:
; 134217728: Array - Laenge = 134217728
; 536870912: Array - Laenge = 536870912
; 1073741824: Array - Laenge = 1073741824
; 8 GByte beschrieben ! ( 8589934592 Byte )
Danke !

Hinweis: Es handelt sich hier um ein stark reduziertes Beispiel zur Problemlösung. Der Code ist frei erfunden. Ähnlichkeiten mit existierenden Codes sind rein zufällig und nicht Absicht des Autors.

Meinen eigentlichen Code veröffentliche ich hier nicht, vielleicht bekomme ich ja ein Patent dafür :lol:

Re: Array - Größe stark eingeschränkt ?

Verfasst: 06.02.2012 18:12
von Danilo
@pp516:
Du kannst auch mal direkt mit API probieren.

Ich weiß jetzt nicht ob der Zugriff über *KompVersionen\q[xQ] evtl. schneller oder langsamer ist
als PB-Arrays. Kannst Du ja mal testen.

Code: Alles auswählen

#EINGBYTE =      1073741824
#VIERGBYTE =     4294967296
#ACHTGBYTE =     8589934592

Structure QuadMemory
    q.q[0]
EndStructure

Macro malloc(_size_)
    ( HeapAlloc_(GetProcessHeap_(),0,_size_) )
EndMacro

Macro free(_mem_)
    HeapFree_(GetProcessHeap_(),0,_mem_)
EndMacro

Macro msize(_mem_)
    ( HeapSize_(GetProcessHeap_(),0,_mem_) )
EndMacro

Macro realloc(_mem_,_size_)
    ( HeapReAlloc_(GetProcessHeap_(),0,_mem_,_size_) )
EndMacro



*KompVersionen.QuadMemory = malloc(#VIERGBYTE)
If *KompVersionen
    Array_Laenge.q = msize(*KompVersionen)
    Debug (Str(#VIERGBYTE) + ": Array - Laenge = " + Str(Array_Laenge.q))     

    For xQ.q = 0 To (#VIERGBYTE / 8 - 1)
        *KompVersionen\q[xQ] = xQ
    Next xQ

    ;free(*KompVersionen)
Else
    Debug "Speicheranforderung fehlgeschlagen"
EndIf