Hi, ich habe eine Datei mit Farbinformationen als Bin mit theoretisch immer aufeinander folgenden 2Bytes als "unsigned short int". Im moment lese ich mit gseek immer 2 Bytes ein, konvertiere die 2Bytes zu einem Short Int und schiebe die nacheinander wie in der Datei sortiert in ein Array. Das einlesen dauert mit 2MB von der SD-Card eben mal 30-60Sekunden. Zuerst dachte ich das es am besten ist die Ganze Datei als char Array mit großem Buffer einzulesen und dann das casten zu starten. Dann habe ich ähnliches mit float und Vector gesehen wo das irgendwie in einem Rutsch geht, nur verstehe ich die ganze Geschichte dahinter nicht. Andere Idee,vielleicht liegen die Bytes schon richtig und können sogar direkt gemapped werden. Was wäre denn jetzt die Sinnvollste Methode?
:
Bearbeitet durch User
Philipp K. schrieb: > Im moment lese ich mit gseek immer 2 Bytes ein Meinst du seekg? Damit kann man gar nichts einlesen sondern nur die Position setzen wo man als nächstes lesen will. Wenn man aber alles nacheinander lesen will ist das überhaupt gar nicht nötig. Du kannst einfach mit read (http://en.cppreference.com/w/cpp/io/basic_istream/read) immer 2 Bytes laden und die Position wird automatisch 2 Bytes weiter gesetzt. Ob du erst alles einließt und dann konvertierst oder beim Einlesen konvertierst sollte ziemlich egal sein. Zeig mal deinen Code.
Welche Plattform? und was ist gseek? Zeige uns doch mal den Code, wie du es gemacht hast.
Ah sorry, bin da noch nicht solang mit c++ das ich alles im Kopf habe, seekg klar, wenn man english kann leuchtets ein also ich meinte Read. Verstanden habe ich die Sache schon soweit das ich den Copy&Paste Code schon für mich angepasst habe. Der war vorher um ein BMP einzulesen.. Mir geht es nur darum das Read durch einen kleinen Buffer im folgenden Code zu langsam sein müsste.
1 | file.seekg (0, file.end); |
2 | size = file.tellg(); |
3 | matrix= new(unsigned short int[size/2]); |
4 | sof=0; |
5 | int counter=0; |
6 | while(sof<size) |
7 | {
|
8 | file.seekg(sof,ios::beg); |
9 | file.read(tmp,2); |
10 | tx = BinToNum(tmp,2); |
11 | matrix[counter] = tx; |
12 | sof+=2; |
13 | counter++; |
14 | }
|
EDIT: Wodran ich gerade hänge:
1 | vector<unsigned short int> buffer(size); |
2 | if (file.read(buffer.data(), size)) |
3 | {}
|
:
Bearbeitet durch User
Es sollte etwas in der folgenden Art gehen: (nicht getestet, nur so als Idee, seekg: nie benutzt...) file.seekg (0, file.end); size = file.tellg(); matrix= new(unsigned short int[size/2]); file.seekg(0,file.begin); file.read(matrix,(size/2) * sizeof(unsigned short int)); Vielleicht hast du aber dann noch Endian-Problem...
A. Horn schrieb: > Vielleicht hast du aber dann noch Endian-Problem... Danke, das Endianproblem kann ich Notfalls im File ändern.. Das sieht schonmal so aus wie es mir nicht in den Sinn gekommen ist. EDIT: Schade, das macht zeitlich keinen unterschied.
:
Bearbeitet durch User
Philipp K. schrieb: > Ah sorry, bin da noch nicht solang mit c++ das ich alles im Kopf habe, > seekg klar, wenn man english kann leuchtets ein also ich meinte Read. > > Verstanden habe ich die Sache schon soweit das ich den Copy&Paste Code > schon für mich angepasst habe. Der war vorher um ein BMP einzulesen.. > > Mir geht es nur darum das Read durch einen kleinen Buffer im folgenden > Code zu langsam sein müsste. > file.seekg (0, file.end); > size = file.tellg(); > matrix= new(unsigned short int[size/2]); new ist keine Funktion, also lass die Klammern weg: matrix= new unsigned short int[size/2]; > sof=0; > int counter=0; > while(sof<size) > { > file.seekg(sof,ios::beg); > file.read(tmp,2); > tx = BinToNum(tmp,2); > matrix[counter] = tx; > sof+=2; > counter++; > } Das läßt sich evtl. schon deutlich beschleundigen, wenn du den seekg wegmachst. Den brauchst du sowieso nicht.
Rolf M. schrieb: > Das läßt sich evtl. schon deutlich beschleundigen, wenn du den seekg > wegmachst. Den brauchst du sowieso nicht. Er braucht es genau zweimal. Einmal um ens Ende der Datei zu springen und dann wieder zurück an den Anfang. Die restlichen in der Schleife sind total unnötig.
Wenn die Bytes in der Datei in der korrekten Reihenfolge abgelegt sind, dann geht auch so etwas:
1 | file.seekg(0, file.end); |
2 | size = file.tellg(); |
3 | matrix = new uint16_t[size / 2]; |
4 | |
5 | file.seekg(sof,ios::beg); |
6 | file.read((uint8_t *) matrix, size); |
Das geht nur dann schief, wenn aus Alignmentgründen die 16-Bit-Werte nicht ohne Lücken im Speicher abgelegt werden können, was manche 32-Bit-Architektur möglicherweise machen könnte. Das lässt sich mit dem sizeof-Operator prüfen, wie groß ist ein Array aus zwei uint16_t? Doppelt so groß wie ein einzelner uint16_t?
Aus der Entfernung siegt es danach aus, als ob es mit "memory mapped file" deutlich schneller ginge (mmap()).
Klaus W. schrieb: > als ob es mit "memory mapped file" Kommt ganz drauf an, was für ein Betriebssystem und was für eine Hardware hier verwendet wird. Das hat der Threadstarter für sich behalten, auch wenn man vermuten kann, daß es hier um ein Programm auf einem PC geht. Allerdings: Warum sollte ein "memory mapped file" hier schneller sein als ein einziger Aufruf von read()? Was glaubst Du, macht ein "memory mapped file" anderes?
so wie ich das verstanden habe, geht es nicht darum, einmal 2 Byte anzufassen, sondern oft hintereinander (sonst würde er die Lesezeiten ja gar nicht merken). Und das geht nach meiner Erfahrung mit mmap meist dramatisch schneller. Hatten wir nicht schon mal diese Diskussion? (Ein AVR wird es nicht sein, wenn er mit seekg hantiert.)
Rufus Τ. F. schrieb: > Was glaubst Du, macht ein "memory > mapped file" anderes? es kopiert nicht dem Speicher 2 mal. Es fallen damit ein paar Kontextwechsel zwischen Kernel und Userspace weg.
Rufus Τ. F. schrieb: > Allerdings: Warum sollte ein "memory mapped file" hier schneller sein > als ein einziger Aufruf von read()? Was glaubst Du, macht ein "memory > mapped file" anderes? Wenn der Inhalt einer Datei bzw. eine Seite davon erstmal in den Speicher eingeblendet ist, geht der Zugriff über einen Pointer darauf wesentlich schneller, einfach weil nichts kopiert werden muß und keinerlei Bibliotheksfunktionen bemüht werden.
Danke für die vielen Tips :) Also da ist kein Geheimnis denn es ist ein RPi und die Datei liegt auf der sdcard vom System. Die Bin Datei beinhaltet ganze Font Zeichensätze die ich selbst gemalt habe um Headless in einen SPI-Buffer zu schreiben.. das funktioniert schonmal mit 25fps und da verschiebe ich den ganzen matrix array mit for Schleifen bei jedem einzelbild. Also im ganzen dauert mir das Laden der Datei zu lang beim Debuggen, wenn ich die Daten direkt ins Headerfile schmeisse mault der RPi beim Kompilieren Speicher voll. Ich finde es trotzdem interessant den richtigen Ansatz zu finden. Hier mal mein wie soll ich sagen.. schauen obs klappt dann mach ichs schick Workaround File: http://bit.do/philipp_k
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.