Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Größeres Array verwenden als der INT-Laufindex zuläßt
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

Themenstarter:

Größeres Array verwenden als der INT-Laufindex zuläßt

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2112

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von chilic am .
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

Themenstarter:

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7537
Herkunft: Waidring

beantworten | zitieren | melden

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!"
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
digi333
myCSharp.de - Member



Dabei seit:
Beiträge: 302

Themenstarter:

beantworten | zitieren | melden

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
Fehler
OverflowException nicht behandelt
private Nachricht | Beiträge des Benutzers
Sarc
myCSharp.de - Member



Dabei seit:
Beiträge: 426

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
OlafSt
myCSharp.de - Member



Dabei seit:
Beiträge: 71
Herkunft: HH

beantworten | zitieren | melden

Würde ein zweidimensionales Array nicht auch gehen ?

float a[][] = new float[Rows][Cols];

oder so ähnlich ;)
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10070

beantworten | zitieren | melden

Zitat
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?
private Nachricht | Beiträge des Benutzers
malignate
myCSharp.de - Member

Avatar #avatar-3206.png


Dabei seit:
Beiträge: 751

beantworten | zitieren | melden

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 );
}
private Nachricht | Beiträge des Benutzers