Autor Beitrag
m.keller
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Mi 22.04.15 15:42 
Hallo ihr Programmiererfreaks,

ich habe ein großes Problem in C# und suche recht lange schon nach einer Lösung.

Ich brauche eine Variable die mir ca. double [400 Millionen] darstellt wo ich meine Werte einfügen kann.
Leider bekomme ich alleine beim initialisieren "OutOfMemmoryException"
Es muss doch irgendwie einen weg geben eine Variable teilweise noch größer zu bekommen oder etwa nicht?

Habt ihr eine Idee unter welchem Stichwort ich da suchen muss oder was ich verwenden kann?

Danke schon ein mal im Voraus.

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 3740
Erhaltene Danke: 762

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Mi 22.04.15 16:07 
Hallo,

brauchst du wirklich so ein großes Array am Stück? Oder reicht auch ein Dictionary<intdouble>, wo du eben nur die benötigten Werte einträgst?

Ansonsten: verwendest du ein 32- oder 64-bit System (denn 400 Mio * sizeof(double) = 400 Mio * 8 = 3.2 GB)? Außerdem gibt es standardmäßig in .NET ein Größenlimit von 2GB, welches du aber mit .NET 4.5 ausschalten kannst, s. With .NET 4.5, 10 years memory limit of 2 GB is over.

Für diesen Beitrag haben gedankt: m.keller
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Mi 22.04.15 16:24 
Danke dir.

mmhhh mir ist jede art recht die sau schnell ist.
Wir wollen es erst ein mal in c# testen (vermutlich viel zu langsam), aber es sollte recht leicht in c++ zu übersetzen sein ansonsten hätte ich auch listen oder so nehmen können.

Die api von wo ich die Werte bekomme ist leider noch eine 32 bit und ich setze ein 64 bit Software auf wo diese eingebunden ist.

Gut zu wissen das man das Limit ausschalten kann. Warum macht man ein Limit in eine Programmsprache?

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4262
Erhaltene Danke: 851


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 22.04.15 17:27 
Zitat:
Warum macht man ein Limit in eine Programmsprache?


Spekulation meinerseits, weil es meist aus Dummheit geschieht einen so großen kontinuierlichen Speicherbereich anzufordern? Und die meisten Entwickler glauben wenn es der Compiler/die Laufzeitumgebung nicht verhindert muß es ja was intelligentes sein ;) Eine gute Entwicklungsumgebung/Sprache sollte aktiv verhindern das ein Programmierer Unfug betreibt. Der c++ Weg den Programmierer als mündigen annähern allwissenden Universalgelehrten anzusehen dem man alle Freiheiten und alle Mittel an die Hand gibt führt dann eben zu entsprechenden Problemen. Wen ich da mal Stroustrup zitieren darf "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off. ". Gute Sprachen sollten eher Foolproof sein.

In C# ist es übrigens relativ leicht sich ein Klasse zu schreiben der einen Indexer bereithält und auf anderen Speicherbereiche(andere Klassen wie zum Beispiel Streams) umlenkt. Wenn du vor allem sequentiellen Zugriffe hast wäre das sogar ohne irgendwas über dein konkretes Projekt zu wissen mit allerhöchster Wahrscheinlichkeit die zu präferierende Lösung.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 850
Erhaltene Danke: 138

Win7
VS 2013, VS2015
BeitragVerfasst: Mi 22.04.15 20:36 
user profile iconm.keller hat folgendes geschrieben Zum zitierten Posting springen:
Warum macht man ein Limit in eine Programmsprache?


Mein Tipp wäre jetzt gewesen, dass das historisch so gewachsen ist. Im Jahre 2000 hat man halt mal einen Int32 für das Feld "Objektgröße" hergenommen und fertig. Irgendwann gab es dann auch genug RAM, sodass das auch tatsächlich eine Limitierung war.

Also entweder das Limit ausschalten (würde ich wohl machen), oder die Lösung für .net 4 und kleiner: Die Daten aufteilen. Also wenn du 400 Mio Werte hast, tust du die unteren 200 Mio in das eine Array und die oberen 200 Mio eben in ein anderes.


Zuletzt bearbeitet von jfheins am Do 23.04.15 19:36, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: m.keller
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Do 23.04.15 08:06 
Danke euch, naja das mit dem Indexer hatte ich mir auch schon gedacht.
Aber das in einen Stream zu leiten, ist das nicht viel zu langsam?
Ich bekomme in der Sekunde ca. 4 Millionen Werte die wollen gespeichert und analysiert werden.

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1620
Erhaltene Danke: 225

WIN7,PuppyLinux
FreePascal,Lazarus,TurboDelphi
BeitragVerfasst: Do 23.04.15 09:48 
Hallo,

wenn ich bedenke, wie schnell p196 von user profile iconjfheins war, ist doch C# sehr schnell.
Und 4e6*8 Byte = 32 Mb/s auf eine Festplatte wegzuschreiben sollte auch ohne PCIe-SSD möglich sein.Im Cache von Windows ist dann ein Vielfaches davon möglich.Ein stream ist sicher noch schneller aber die Speichergrenzen bei 64-Bit wirst Du wohl kennen.
Oder Memory-Mapped-Files www.codeproject.com/...s-with-the-NET-Frame

Ich weiß aber nicht, wie aufwändig die Daten verarbeitet werden, ob wirklich alle zeitgleich im Zugriff sein müsssen oder eben abschnittweise und dass man dann nur die Ergebnisse dieser Abschnitte zusammenführt.

Gruß Horst
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4262
Erhaltene Danke: 851


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 23.04.15 09:54 
Zitat:
Aber das in einen Stream zu leiten, ist das nicht viel zu langsam?


Es kommt drauf an was du für einen Zugriff du auf die Daten brauchst. Wenn du Daten annimmst, anguckst und wegschreibst, rein sequentieller Vorgang, sollte das ausreichend schnell sein. Wenn du gleichzeitig random Zugriff auf die bereits abgelegten Daten brauchst wird es kompliziert das performant zu halten. Wenn die Datenstruktur größer als der verfügbare physische Speicher (egal ob wegen einem künstlichem Limit oder einfach wegen fehlender physischer Verfügbarkeit) ist das dann aber eher eine Sprach/Framework-unabhängig Problematik.
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Do 23.04.15 10:16 
puh.. das scheint ein sehr komplexe Sache zu werden.

Eine Kurze Beschreibung. die Daten hole ich in einem Thread so schnell es geht ab.
Diese lege ich in einem Array in einer anderen Klasse ab (es ist ein art Ringpuffer dafür vorgesehen, leider zu klein), von dort hole ich mit einem anderen Thread blockweise die Werte ab und verarbeite diese. ab da an könnte ich die Menge an werte reduzieren. aber vorher brauche ich alle mögliche um die Block-Auswertung zu gestalten.

Ich hatte schon überlegt ob ich mir in der Klasse ein Logik ein baue die es ermöglicht mehrere Arrays hintereinander zu bekommen.
Problem ist aber, dann bin ich nicht flexible genug von der Größe, lege ich drei Variablen an bin ich darauf beschränkt.

Das Array ist schon recht komplex double[,] (double[Standort,Wert]) somit könnte es auch sein wenn Standort wächst wird es ziemlich schnell ziemlich Groß.

Gruß

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4262
Erhaltene Danke: 851


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 23.04.15 11:27 
Dann ist wohl eher hilfreich die Blöcke richtig (frühzeitig) so zu schneiden das man handhabbare Blöcke bekommt die auch auch als solcher Block weiterverarbeitet werden können. Der Gedanke mit Streams ist dann vermutlich eher weniger hilfreich oder wenn dann nur eine sekundäre Überlegung wert wenn du tatsächlich einen Buffer zwischen Empfang und Weiterverarbeitung brauchst der potentiell Größer als der physisch verfügbare Ram ist.

Nebenbei in einem Jagged Array (double[][]) wäre jede Dimension ein eigenes Array mit jeweils eigenem Speicherlimit im Gegensatz zu einem mehrdimensionalen Array double[,]. Wieviele Werte sind den in der Werte Dimension?

Für diesen Beitrag haben gedankt: m.keller
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Do 23.04.15 12:02 
sobald die ersten Daten vorhanden sind hole ich mir Passende Blöcke und gebe den Puffer wieder in dem Bereich frei. Damit es etwas Handelbar bleibt.

Die Dimension Werte entspricht den geforderten 400 Millionen, die Dimension Standort könnte bis zu 16 annehmen.
Und das ist schon ein Haufen Daten.
Und so wie ich Vermute müssen die schleifen zum Analysieren verdammt schnell sein um den Puffer frei zu bekommen.

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1620
Erhaltene Danke: 225

WIN7,PuppyLinux
FreePascal,Lazarus,TurboDelphi
BeitragVerfasst: Do 23.04.15 13:09 
Hallo,

da stellt sich die Frage, ob bei 400e6 Daten pro Standort==100 Sekunden und nur 4e6 Daten/s diese überhaupt in Echtzeit verarbeitet werden müssen.Mach doch für jeden Standort einen stream und thread für deren Verarbeitung.Aber das hängt natürlich von der Art der Verarbeitung ab, ob die Daten pro Standort verarbeitet werden können.Dazu gibt es ja keinen Einblick.

Gruß Horst
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Do 23.04.15 13:35 
richtig 100 Sekunden wären die maximale Vorratshaltung der Daten. Ich bekomme die Daten aus der api für jeden Standort hintereinander. (wert 1[Standort 1,2,3,4...] Wert 2[Standort 1,2,3,4...]

Sie sollten so Echtzeit nahe bearbeitet und angezeigt werden wie möglich.

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1620
Erhaltene Danke: 225

WIN7,PuppyLinux
FreePascal,Lazarus,TurboDelphi
BeitragVerfasst: Do 23.04.15 14:26 
Hallo,

alle 1/4e6 -> alle 250 ns ein neuer Wert. Da kann eine heutige CPU schon einiges rechnen, wenn Daten schnell greifbar sind, (250* CPUfreqInGhz) = CPU_Takte.
Die Darstellung kann aber sehr viel Zeit kosten.
Aber, was da gerechnet werden soll, können wir immer nur noch raten ;-)

Gruß Horst
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Do 23.04.15 14:56 
z.b. soll die Frequenz ermittelt werden und zyklisch Angezeigt werden

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1620
Erhaltene Danke: 225

WIN7,PuppyLinux
FreePascal,Lazarus,TurboDelphi
BeitragVerfasst: Do 23.04.15 17:14 
Hallo,

also etwas mit FFT.Ob sotwas lomont.org/Software/...c/FFT/LomontFFT.html schneller ist, wer weiß.Versuch macht klug.
Kann man nicht eine C-DLL einbinden?
fftw.org/ freeware vom MIT ist doch recht fix und nutzt auch SSE2 www.fftw.org/speed/CoreDuo-3.0GHz-icc64/
aber was bedeuten dabei die MFlops?
Für Windows die dll: fftw.org/install/windows.html

Gruß Horst
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 451
Erhaltene Danke: 83

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Fr 24.04.15 11:23 
Nachdem wir nun langsam aber sicher dem TE aus der Nase gezogen haben, was tatsächlich passiert, ergibt sich doch ein anderes Bild. IMHO ist es hier eher entscheidend, wieviele der empfangenen Meßwerte in einen Block gehören. Nehmen wir 100 Meßwerte, so lassen die sich doch problemlos in ein Array mit 100 Elementen stecken. Die Meßwerte zu empfangen dauert 25µs.
In einem parallel laufenden Thread wird die FFT berechnet. Wenn diese Berechnung > 25µs dauert, wird es spannend; denn dann sollte man vllt. mit Queues arbeiten und mehrere FFT-Threads rechnen lassen (jeden auf einem eigenen CPU-Core), bis eben die 25µs erreicht sind. Ist dies nicht möglich, ist die Kiste zu langsam, denn egal wie man es dreht: Du kriegt die Daten nicht schnell genug "verrechnet", ergo wird jeder nur denkbare Buffer irgendwann volllaufen.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: m.keller
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1620
Erhaltene Danke: 225

WIN7,PuppyLinux
FreePascal,Lazarus,TurboDelphi
BeitragVerfasst: Sa 25.04.15 07:56 
Hallo,

man kann ja auch nur ein Teil der Daten zur Visualisierung benutzen, schliesslich reicht ja 50 Hz für eine flüssige Darstellung. Wenn man 2048 Punkte nimmt, falls man das überhaupt braucht, sind die ja in 512 µs da.Aber in 25 ms sicher, je nach CPU natürlich, verrechnet.
Also Daten kontinuirlich wegschreiben und eben immer wieder ein kleines Häppchen zur Darstellung verarbeiten.
Was interessant wäre, ob es FFT gibt, wo man an einem Ende etwas Werte hinzufügt und am anderen wegnimmt.

Gruß Horst

Für diesen Beitrag haben gedankt: m.keller
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Mo 27.04.15 08:48 
Vielen dank für die ganzen Antworten.

ihr habt mich ein stück weiter gebracht.
Ich werde mir die Klasse so abändern, dass ich die Variablen maximal 2 GB groß mache.
Dann bin ich unabhängiger.

Alles andere bedarf vermutlich eine menge test um die Abhängigkeit von CPU so wie alle anderen Elemente zu untersuchen und das Optimale heraus zu finden.

Danke

Gruß

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)
m.keller Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win xp, Win 7
C# (VS 2008)
BeitragVerfasst: Mi 29.04.15 09:42 
So nun habe ich mal versucht es mit einem Jagged Array versucht.
Leider bekomme ich dort aber nur eine Initialisierung von ca. 80 Millionen hin.
Was läuft da falsch?

Es müsste doch laut Ralf so sein dass ich mindestens die 200 Millionen hin bekommen würde.

200 Millionen x 8 byte = 1,6 GB sollte doch dann möglich sein

1 GB --> 1073741824 byte
2 GB --> 2147483648 byte

doubel besteht aus 8 byte

2147483648 / 8 = 268435456

Andersherum könnte ich maximal 268435456 werte speichern oder?

Sind die ganzen Pointer die im Hintergrund verwendet werden so wie sonstige Deklarationen für das Array so groß, dass ich nur ca. 1/4 von der Größe verwenden kann?

_________________
Der gesunde Menschenverstand ist nur eine Anhäufung von Vorurteilen, die man bis zum 18. Lebensjahr erworben hat. (Albert Einstein)