Ich brauche ein Float-Array von mehr als 2^31 Zellen, aber wie?
int cells = Rows*Columns; // 17001*216411=3679203411
float[] f = new float[cells];
Man sieht schnell, dass cells größer ist als der Wertebereich von Integer.
Du weißt dass du dazu über 14 GB freien Speicher brauchst? Vielleicht hat sich deine Idee ja schon mit dieser Überlegung erledigt 😃
Falls nicht, könntest du mit einer eigenen Klasse nachhelfen, die einen long Index bekommt und damit eine interne Struktur ausliest. Dir würden zwei Arrays mit int Index genügen, die anhand des höchsten Bits in deiner Zahl unterschieden werden.
Was machst du denn dass du da wirklich so umfangreiche Daten hast?
Edit: Was mir auch noch einfällt, sind wirklich alle Zellen des Array gefüllt oder nur sehr wenige? In letzterem Fall könntest du evtl. auch ein Dictionary verwenden.
Ich hab 32 GB und noch eine 512 GB SSD Festplatte zum auslagern. Sollte reichen. Wie sieht eine eigene Array-Klasse aus mit einem long als Index-Variable?
Hallo digi333,
wenn du .net 4.5 benützt, so kannst du das 2GB-Limit für ein Objekt außer Kraft setzen indem <gcAllowVeryLargeObjects> auf true gesetzt wird.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Hallo digi333,
es wäre sicher nicht so aufwändig, eine eigene Array-/List-Klasse zu schreiben, die intern ein Array von Arrays benutzt, welche alle kleiner als 2GB sind. Man muss den Index dann nur (mit Bitoperationen) aufteilen, um anschließend mit zwei Indexzugriffen an den gewünschten Wert zu kommen. Das hätte den Vorteil, dass der Speicher nicht in einem zusammenhängenden Stück benötigt wird, sondern es reicht, wenn die freien Speicherbereiche groß genug für die Teil-Arrays sind.
herbivore
Ich hab das Projekt in VS2012 mit x64 und in der "App.config" folgendes eingetragen.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<gcAllowVeryLargeObjects enabled="true" />
</runtime>
</configuration>
Im Hauptprogramm steht nicht mehr als...
long t = 3679203411;
float[] a = new float[t];
Dennoch kommt eine > Fehlermeldung:
OverflowException nicht behandelt
Du solltest auch den Kommentar auf der MSDN Seite berücksichtigen:
Zitat von:
Element
The maximum number of elements in an array is UInt32.MaxValue.
Würde ein zweidimensionales Array nicht auch gehen ?
float a[][] = new float[Rows][Cols];
oder so ähnlich 😉
Ich brauche ein Float-Array von mehr als 2^31 Zellen, aber wie?
Warum?
In 105% aller Fälle kommt so eine Anforderung weil sich jemand nicht vorher mit Datendesign oder den Anforderungen auseinandersetzt.
Warum meinst du also ein zusammenhängendes Array von mehr als 16GB haben zu müssen?
Im übrigen kann ich mir auch gut vorstellen, dass es aufgrund der Fragementierung des Speichers gar nicht möglich ist, ein so großes Array am Stück zu allokieren.
Mal dahingestellt, dass du es wirklich brauchst, würde ich dir schon dafür zu vielen kleinen Arrays raten. Also 10MB Blöcke oder so. Wenn du das geschickt machst, kannst du auch was schreiben, um das auf die Platte zu bringen und mit weniger Speicher auskommen.
sowas wie:
byte[] Get(long position)
{
long pageNumber = position / pageSize;
var page = lruCache[pageNumber ];
if (page == null)
{
page = ReadFromFS(pageNumber );
var replaced = lruCache.Set(pageNumber, page);
if (replaced != null && replaced.PageNumber != pageNumber && replaced.HasChanged)
{
WriteToFS(replaced);
}
}
return page.Get(position - page * pageNumber );
}
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::