Forum: PC Hard- und Software Große Datenmengen in einem C-Programm


von mr08b002 (Gast)


Lesenswert?

Hallo,

ich schreib Gerade ein Programm (in C) das mit 3D-Daten (.obj) hantiert. 
dabei liegen die Eckpunkte des Modells als Vektoren im 3D-File vor.
Meine Frage ist nun wie man mit großen Datenmengen in einem C-Programm 
am besten umgeht. Momentan hab ich sie in einem großen Array (3 x n) 
gespeichert. Alternativ hab ich mir überlegt die Vektoren in ein 
txt.-File zu schreiben und jedesmal von dort einzulesen. Kann dadurch 
evtl. das Programm ausgebremst werden?
Jedenfalls kommen mir beide Lösungsansätze etwas suboptimal vor. Da 
gibts doch sicherlich eine bessere und elegantere Lösung.

lg
michael

von Rolf Magnus (Gast)


Lesenswert?

mr08b002 schrieb:
> Hallo,
>
> ich schreib Gerade ein Programm (in C) das mit 3D-Daten (.obj) hantiert.
> dabei liegen die Eckpunkte des Modells als Vektoren im 3D-File vor.
> Meine Frage ist nun wie man mit großen Datenmengen in einem C-Programm
> am besten umgeht.

Was sind "große Datenmengen"? 10 kB? 10 MB? 10 GB?

> Momentan hab ich sie in einem großen Array (3 x n)
> gespeichert. Alternativ hab ich mir überlegt die Vektoren in ein
> txt.-File zu schreiben und jedesmal von dort einzulesen. Kann dadurch
> evtl. das Programm ausgebremst werden?

Die Daten müssen natürlich eingelesen werden, aber sobald das passiert 
ist, wird nichts ausgebremst.

> Jedenfalls kommen mir beide Lösungsansätze etwas suboptimal vor. Da
> gibts doch sicherlich eine bessere und elegantere Lösung.

Dazu mußt du aber noch mehr Details angeben.

von Sven P. (Gast)


Lesenswert?

Mögliche Wege und Probleme:

. Datenstamm komplett einlesen, wie bisher. Oder sinds mehrere hundert 
Megabytes?
. Ein Speichermapping einrichten, den Rest macht das Betriebssystem.
. Bei 32-Bit-Systemen wirds über 4GB kompliziert.
. Bei dem Windoof-FAT32-Spielzeug wird es ab 4GB in einer Datei 
schwierig.

Ich wäre für das Speichermapping. Schlimmstenfalls lässt sich das wie 
ein Guckloch über die Datei verschieben.

von Rolf Magnus (Gast)


Lesenswert?

Sven P. schrieb:
> Mögliche Wege und Probleme:
>
> . Datenstamm komplett einlesen, wie bisher. Oder sinds mehrere hundert
> Megabytes?

Selbst das kann schon in ein paar Sekunden gehen.

> . Ein Speichermapping einrichten, den Rest macht das Betriebssystem.
> . Bei 32-Bit-Systemen wirds über 4GB kompliziert.

Es wird schon davor kompliziert.

> . Bei dem Windoof-FAT32-Spielzeug wird es ab 4GB in einer Datei
> schwierig.

"Schwierig" suggeriert, daß es irgendwie möglich wäre.

> Ich wäre für das Speichermapping. Schlimmstenfalls lässt sich das wie
> ein Guckloch über die Datei verschieben.

Kommt halt, wie gesagt, auf den Anwendungsfall an.

von Sven P. (Gast)


Lesenswert?

Sei mal nicht so kleinlich. Windows taugt halt recht wenig, das betrifft 
nicht nur das Dateisystem...

Je nachdem, was mit den Daten angestellt werden soll, reichen ja 
vielleicht schon einfache Dateizugriffe. Wenns doch ganz im 
Arbeitsspeicher landen soll, ist eine vernünftige Wahl von Datentypen 
wichtig.

von mr08b002 (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Dazu mußt du aber noch mehr Details angeben.

Also also als erstes sollte ich vielleicht erwähnen dass ich das 
Programm für Linux schreibe (32bit).

Rolf Magnus schrieb:
> Was sind "große Datenmengen"? 10 kB? 10 MB? 10 GB?

Die größen der Dateinen variiert sehr stark. Sie sollte allerdings 10MB 
nicht überschreiten. (Im vergleich mit Audio oder Videodaten sind die 
Dateien also gar nicht so groß).

Rolf Magnus schrieb:
>> Alternativ hab ich mir überlegt die Vektoren in ein
>> txt.-File zu schreiben und jedesmal von dort einzulesen. Kann dadurch
>> evtl. das Programm ausgebremst werden?
>
> Die Daten müssen natürlich eingelesen werden, aber sobald das passiert
> ist, wird nichts ausgebremst.

Ich hab dabei daran gedacht die TXT-Datei als Zwischenspeicher zu 
verwenden. Im Programmablauf müsste dann ständig ein Such-Algorithmus 
drüberlaufen. Die Datei müsste also ständig gelesen werden. Deshalb die 
Sorge mit dem ausbremsen.

Zu guter letzt sollte ich vielleicht noch den grundlegenden 
Programmablauf beschreiben:

Eine Object Datei schaut "von innen" etwa so aus:
1
mtllib file.mtl
2
o Cube_Cube.001
3
v 4.999997 0.000000 -4.999998
4
v 4.999997 -0.000000 4.999998
5
v -4.999997 -0.000000 4.999998
6
v -4.999996 0.000000 -4.999999
7
v 4.999999 5.000000 -4.999996
8
v 4.999994 5.000000 5.000000
9
v -5.000000 5.000000 4.999995
10
v -4.999995 5.000000 -5.000000
11
usemtl (null)
12
s off
13
f 1 2 3 4
14
f 5 8 7 6

Mich interessieren nun nur die Zeilen die mit "v" beginnen (das sind 
Vektoren). Diese bestehen wie man sieht aus jeweils 3 Flieskommazahlen. 
In realen Files kommen bis zu mehreren 10-tausend solcher Zeilen vor. 
Diese Vektoren möchte ich nun in irgend einer From in meinem Programm 
zur Verfügung haben um sie zB. in ein Diagramm zu Zeichnen, zu filtern, 
zu verbinden usw.. Meine Frage ist nun wie ich diese Datenmenge am 
besten im Programm abspeichere um sie jederzeit lesen und manipuliern zu 
können. Momentan hab ich sie in einem Array das in etwa so aussieht:
1
int arVector[3][16384]

ich find ein Array dieser Größenordnung etwas ungewöhnlich oder irre ich 
mich und es werden in der Praxis durchaus solche Arrays verwendet?

danke
Michael

von mr08b002 (Gast)


Lesenswert?

mr08b002 schrieb:
> int arVector[3][16384]

sorry, natürlich schauts eher so aus:
1
double arVector[3][16384];

von Sven P. (Gast)


Lesenswert?

mr08b002 schrieb:
> Die größen der Dateinen variiert sehr stark. Sie sollte allerdings 10MB
> nicht überschreiten. (Im vergleich mit Audio oder Videodaten sind die
> Dateien also gar nicht so groß).
Die sind ja winzig!

> Ich hab dabei daran gedacht die TXT-Datei als Zwischenspeicher zu
> verwenden. Im Programmablauf müsste dann ständig ein Such-Algorithmus
> drüberlaufen. Die Datei müsste also ständig gelesen werden. Deshalb die
> Sorge mit dem ausbremsen.
Naja, wie soll es dadurch schneller werden? 10MB kannst du problemlos im 
Arbeitsspeicher vorhalten.

> Mich interessieren nun nur die Zeilen die mit "v" beginnen (das sind
> Vektoren). Diese bestehen wie man sieht aus jeweils 3 Flieskommazahlen.
> In realen Files kommen bis zu mehreren 10-tausend solcher Zeilen vor.
> Diese Vektoren möchte ich nun in irgend einer From in meinem Programm
> zur Verfügung haben um sie zB. in ein Diagramm zu Zeichnen, zu filtern,
> zu verbinden usw.. Meine Frage ist nun wie ich diese Datenmenge am
> besten im Programm abspeichere um sie jederzeit lesen und manipuliern zu
> können. Momentan hab ich sie in einem Array das in etwa so aussieht:
>
>
1
int arVector[3][16384]
>
> ich find ein Array dieser Größenordnung etwas ungewöhnlich oder irre ich
> mich und es werden in der Praxis durchaus solche Arrays verwendet?
Also ein Double-Array, hast dich ja korrigiert.

Überlege zuerst, welchen Wertebereich die Angaben in deiner Datei 
abdecken. Ist das wirklich doppelte Genauigkeit (double, 8 Bytes), oder 
doch eher einfache (float, 4 Bytes)?

Ansonsten ist an deinem Array eigentlich wenig auszusetzen. Ich würde es 
dynamisch machen, also mit malloc() reservieren. Dazu müsstest du im 
ersten Lauf die Zeilen zählen.
Selbst die Datei noch zwischenzuspeichern halte ich für unnötig. Darum 
kümmert sich das Betriebssystem schon.

von Juergen (Gast)


Lesenswert?

Arrays dieser Größenordung sind heutzutage auf einem Desktop-PC kein 
Problem. Solange du insgesamt nicht mehr als 100MB verbrätst, brauchst 
du dir keine Sorgen zu machen.

von ich (Gast)


Lesenswert?

pack des Zeug in den RAM, am besten mit malloc besorgen, und gut ist.

von (prx) A. K. (prx)


Lesenswert?

Gehört jedenfalls ins RAM. Organisiere die Daten so, dass der Zugriff 
hauptsächlich sequentiell erfolgt, also mindestens ein paarhundert Bytes 
am Stück verwendet werden, nicht wild durcheinander oder hüpfend.

von mr08b002 (Gast)


Lesenswert?

Sven P. schrieb:
> Überlege zuerst, welchen Wertebereich die Angaben in deiner Datei
> abdecken. Ist das wirklich doppelte Genauigkeit (double, 8 Bytes), oder
> doch eher einfache (float, 4 Bytes)?

Eigentlich ist es nur ein float. Ich hab nur deshalb einen double 
verwendet weil die Funktion atof einen double-Wert zurückliefer. Das 
könnt ich aber wirklich noch abändern um ein bisschen was einzusparen.

Sven P. schrieb:
> Ich würde es
> dynamisch machen, also mit malloc() reservieren.

War eigentlich auch geplant. Das ist nur jetzt zum testen so 
programmiert worden.

Danke für eure Hilfe. Dank euch kann ich jetzt ruhigen Gewissens weiter 
programmieren.

lg
Michael

von mr08b002 (Gast)


Lesenswert?

A. K. schrieb:
> Organisiere die Daten so, dass der Zugriff
> hauptsächlich sequentiell erfolgt, also mindestens ein paarhundert Bytes
> am Stück verwendet werden, nicht wild durcheinander oder hüpfend.

wie mach ich so etwas? malloc kann ich nur die Größe des benötigten 
Speichers übergeben. Gibt es eine andere Funktion mit der ich einen 
zusammenhängenden Bereich im Speicher reservieren kann oder macht das 
die malloc-Funktion sowieso?

von (prx) A. K. (prx)


Lesenswert?

mr08b002 schrieb:

> wie mach ich so etwas? malloc kann ich nur die Größe des benötigten
> Speichers übergeben.

Ich bezog mich auf die Reihenfolge des Zugriffs auf die Daten im 
Speicher. Wenn die Zeit für die Verarbeitung keine Rolle spielt, dann 
vergiss es. Wenn doch, dann ist sequentieller Zugriff auf RAM schneller 
als hüpfender. Ungünstig ist es beispielsweise, bei einem Array den 
Spalten statt den Zeilen zu folgen.

von Sven P. (Gast)


Lesenswert?

mr08b002 schrieb:
> Eigentlich ist es nur ein float. Ich hab nur deshalb einen double
> verwendet weil die Funktion atof einen double-Wert zurückliefer. Das
> könnt ich aber wirklich noch abändern um ein bisschen was einzusparen.
Genaugenommen nicht nur ein 'Bisschen', sondern die Hälfte.

atof ist veraltet, heute sind strtod, strtof und strtold angesagt, und 
da hast du dein float :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.