Auslesen einer Datei



  • Hallo,

    gibt es in c++ irgendwie eine Möglichkeit bei Auslesen einer Datei von hinten an zu fangen ?

    Weiß einer von euch ob es möglich ist eine Datei parallel mit openMP aus zu lesen ?

    Grüsse

    eicon



  • Einfach alles in einen std::string schreiben und per std::string::reverse_iterator loopen und weiterverwenden?



  • Ja, aber da habe ich ja die Datei schon ausgelesen...

    Es geht darum dass ich eine sehr grosse Datei habe und diese am besten parallel von hinten und vorne auslesen moechte



  • Hm, dann bleibt dir nichts übrig als bis zum Ende zu springen und "zurückzulesen":

    #include <iostream> 
    #include <fstream> 
    using namespace std; 
    
    int main() 
    { 
        char zeichen=0; 
        ifstream file("test.txt"); 
        int pos = -1; 
    
        file.seekg(pos, ios::end); 
    
        while(file.get(zeichen)) 
        { 
            cout << zeichen; 
            pos--; 
            file.seekg(pos, ios::end); 
        } 
        cout << endl; 
    }
    

  • Mod

    Open MP hat keine besondere Unterstützung von paralleler I/O. Es bleibt alles dem Programmierer überlassen, wie er die Ein-/Ausgabe organisiert. Wenn du auf einem Großrechner arbeitest, dürfte der Hersteller des Speichersystems in der Regel aber irgendwelche Methoden zum parallelen Zugriff vorgesehen haben. Musst du mal in der Doku gucken oder jemanden vom Support fragen. Es gibt auch sicherlich Kurse, die dir die Grundlagen der parallelen Ein-/Ausgabe beibringen - die Idee mit dem gleichzeitigen Lesen von vorne und von hinten ist nämlich eine sehr ungewöhnliche Methode, Daten zu organisieren.

    Oder Missverstehe ich dich und du willst nur für Heimcomputer programmieren und verstehst kein Wort von dem was ich oben geschrieben habe? Dann vergiss das mit dem gleichzeitigen Lesen an mehreren Stellen. Wenn das Speichersystem nicht parallel ausgelegt ist, bremst du dadurch im Zweifelsfall alles aus.



  • Hallo,

    ich hänge mich mal an dieser Stelle in den Thread ein.

    Ich habe ein ähnliches Problem und frage mich ob der vorhergehende Post auch auf mich zutrifft.

    Ich habe eine Workstation mit 4CPUs und ein Programm, dass ich mit (open)MPI quasi-parallelisiert habe. "Quasi" deshalb, weil ich einfach das Programm mehrfach starte und über MPI einen zu bearbeitenden Parameterraum auf die Prozesse aufteile.
    Nun brauchen meine Prozesse allerdings Eingabedaten. Diese habe ich bisher immer mit einem ifstream eingelesen. In der "parallelen" Version bricht mir mein Programm jetzt an dieser Codezeile ab:

    ifstream file(filename.c_str());
      if( !file.is_open() )
        {
          cerr << "\t*** Could not open file " << filename
               << " ... data not read" << endl;
          cerr << "----- exit ----- "<<endl;
          exit(1);
        }
    

    Ich interpretiere: das File ist schon geöffnet und kann nicht erneut "parallel" geöffnet werden. Kann ich irgendwie dieses Problem lösen? Nutzt mir zB. MPI-I/O etwas?
    Ich habe keinerlei Erfahrung und kann mit den Sachen die ich mit googlen gefunden habe nicht wirklich etwas anfangen. Ein Tutorial zu den basics paralleler I/O würde mir schon weiterhelfen.

    Viele Grüße,

    zebro


  • Mod

    Beim reinen lesen sollte das eigentlich nicht passieren. Da muss noch ein anderer Fehler vorliegen.

    Und ja: Mit MPI I/O kann man von mehreren Prozessen aus gleichzeitig auf eine Datei zugreifen. Lesend und Schreibend, aber erst das Schreiben ist etwas, was sonst nicht so einfach wäre.



  • Hi Leutz,

    zwar schon etwas her, aber ich hätte da einen logischen Denkansatz.

    Zunächst:

    gibt es in c++ irgendwie eine Möglichkeit bei Auslesen einer Datei von hinten an zu fangen ?

    In Binärdateien kann man den Zugriffspointer frei positionieren.
    Z.B. mit fseek(). Da kann man relativ vom Anfang, relativ von der aktuellen Position und relativ vom Dateiende bytegenau positionieren. Ansonsten kann man bei Textdateien vollständig bzw. gewisse Abschnitte einlesen und dann mit String-Funktionen den Stream durchsuchen. Aber das wurde ja hier schon gesagt: "ans Ende springen und Rückwärts lesen".

    ----------------------------------------------

    Nun aber zur Parallelisierung mit OpenMP oder auch mit anderen Parallelisierungsansätzen. Da ich selbst gerade anfange, mich da rein zu arbeiten, würde mich das Filehandling bei OpenMP bzw. bei der Parallelisierung im Allgemeinen auch sehr interessieren.

    Nach langen Recherchen fiel mir eine Möglichkeit ins Auge und zwar ist dies auch bekannt beim Einsatz von Clustern und das verteilte Bearbeiten bzw. Durchsuchen von Datenbanken und / oder Dateien.

    Ausgehend von zwei zu parallelisierenden Lesemethoden (von Anfang bis zur Hälfte und vom Ende bis zur Hälfte bzw. von der Hälfte bis zum Ende) wäre eine Möglichkeit, zwei Threads zu erzeugen, wobei ein Thread eben vom Anfang bis zur Hälfte liest / durchsucht und der zweite Thread parallel vom Ende zur Hälfte bzw. einfacher von der Hälfte zum Ende.
    Ich weiß jetzt allerdings nicht, inwieweit es möglich ist, in einer Instanz, parallel auf ein und dieselbe Datei zuzugreifen (zumindest lesend). Das liese sich jedoch auch leicht lösen, indem jeder Thread vorher ein eigenes Duplikat erhält (kommt natürlich auf die Größe der Datei an, ob sich das lohnt). Ein Flaschenhals dabei könnten dann jedoch die dabei verwendeten Busse und / oder die Festplattencontroller werden.

    Je nach Dateityp (z.B. Datenbank mit n Datensätzen), könnte man mal weiter gesponnen, die zu durchsuchende Datei durch n viele Threads durchsuchen lassen, indem jeder Thread jeweils einen eigenen Datenbereich der Datei zum Durchsuchen erhält (etwa: Anzahl Threads -und Dateibereiche = (Datei / Anzahl Datensätze)). Um die Performance nicht all zu stark zu beeinträchtigen, muss man glaube ich (schlagt mich tot, habs zumindest gelesen) dabei eine möglichst optimale Körnung auswählen. Soll heißen, dass zu viele Aufsplittungen durch viele Threads aufgrund des anzustehenden Overheads, auch zum Nachteil werden können. Zu feinkörnig gewählt, könnte dabei zu viel Overhead entstehen (wie gesagt, könnten die Busse und Festplattencontroller ein Flaschenhals sein) und zu grobkörnig gewählt, kann wiederum nicht die optimale Leistung aus einem Parallelsystem heraus geholt werden (verschwendete Leistung).

    Je größer eine Datenbank / Datei ist, umso mehr Threads wären da logisch die bessere Wahl. Ist sie hingegen relativ klein, reichen auch nur ein paar Threads bzw. wie im Beispiel auch nur zwei. Würde man also zwei Threads, je eine Hälfte der Datei durchsuchen lassen, hätte man THEORETISCH die doppelte Leistung. Dabei sollte man auch stets den an zufallenden Overhead berücksichtigen (vlt. hat die CPU genug Leistung, aber der Systembus, SATA-Bus oder PATA-Bus gibt nicht mehr her, als logisch nötig wäre; etc.). Gerade bei Einsatz nur einer Festplatte hätte man ein Problem bzw. gar wieder eine Halbierung, da der Schreib- und Lese-Kopf zur selben Zeit wohl nur lesen oder schreiben kann. Da würde es sich anbieten, wie im Beispiel, den einen Thread mit der HDD/SDD-Kopie hantieren zu lassen und ein Duplikat für den zweiten Thread auf einen anderen Speicher zu transferieren, etwa zweite Festplatte (fällt bei IDE-Master-Slave dann ja wohl wieder flach) oder besser den schnelleren Arbeitsspeicher. Wenn genug RAM verfügbar, könnte man auch die Datei/Datenbank zweimal vollständig in den RAM laden lassen.

    So, ditt wars dann auch schon von meiner Seite.
    Was haltet Ihr davon bzw. hättet Ihr daran was auszusetzen oder seht Ihr in dieser Herangehensweise noch Optimierungen?
    Ich wäre auch sehr dankbar für jeden Tipp und andere File-I/O-Methoden beim Thema "Parallelität".

    Grüße

    Schlitzauge 🙂 🙂 🙂 🙂 🙂


  • Mod

    In OpenMP liegt die Verantwortung für parallele IO gänzlich beim Programmierer.

    Ich behaupte auch mal, dass du, falls der dahinterliegende Massenspeicher nicht speziell da drauf ausgelegt ist, eher verlierst statt gewinnst, wenn du Dateien parallel liest/schreibst. Wenn dein Flaschenhals IO ist, dann ist die Lösung eher in der Hardware zu suchen, als in der Software. Zum Beispiel, indem man eben so einen Massenspeicher installiert, der parallel lesen/schreiben kann.


Anmelden zum Antworten