Multithreading Flaschenhals



  • In der Regel ist die Festplatte der Flaschenhals. Selbst ein Kern ist schnell genug um die Festplatte voll auszulasten, daher macht Multithreading dort wenig Sinn.



  • Ok guter Punkt .. daher bei reinem Lesezugriff muss man globale Resourcen nicht locken (kann man das allgemein so sagen?)

    In der selben Anwendung gibt es einen zweiten Moment in dem die Threads ihre Daten in eine globale std::list speichern. Jeder Thread macht also einfach ein list->push_back(meineDaten).
    Ist hier ein lock der list sinnvoll oder auch unnötig?

    ---> Gibt es eine Möglichkeit die Disk zu beschleunigen/auszutricksen? ...



  • GreedyRaccoon schrieb:

    Ok guter Punkt .. daher bei reinem Lesezugriff muss man globale Resourcen nicht locken (kann man das allgemein so sagen?)

    Ja. Die Daten können zwischendurch ja nicht geändert werden. Das locken ist nur notwendig, um sicherzugehen das die Daten zwischendurch nicht von jemand anderes geändert werden. Beachte, dies gilt nur wenn nirgendwo anders nebenbei die Daten beschrieben werden.

    GreedyRaccoon schrieb:

    In der selben Anwendung gibt es einen zweiten Moment in dem die Threads ihre Daten in eine globale std::list speichern. Jeder Thread macht also einfach ein list->push_back(meineDaten).
    Ist hier ein lock der list sinnvoll oder auch unnötig?

    Absolut! Geschieht auch nur _irgendwo_ nebenbei ein Schreibzugriff, so muss jeglicher Schreibb- und Lesezugriff synchronisiert werden mittels Locks. std::list ist nicht von sich aus Threadsicher.

    GreedyRaccoon schrieb:

    ---> Gibt es eine Möglichkeit die Disk zu beschleunigen/auszutricksen? ...

    Kauf dir ne SSD. 😉



  • Meine Platte zurzeit

    Typ und Anschluss Festplatte - SATA II
    Speicherkapazität / Cache 500.0 GB / 16 MB
    Geschwindigkeit 7200 rpm

    Was wäre eine Platte welche den QuadCores genüge tun würde? (so, dass diese wieder zum Flaschenhals werden?)



  • GreedyRaccoon schrieb:

    Was wäre eine Platte welche den QuadCores genüge tun würde? (so, dass diese wieder zum Flaschenhals werden?)

    Gar kein, selbst ein 1GHz-Prozessor wird deutlich schneller sein als ne SSD-Platte.



  • Nimm vier Platten im RAID-0-Verbund und du hast damit keine Probleme mehr. 😉



  • Fellhuhn schrieb:

    Nimm vier Platten im RAID-0-Verbund und du hast damit keine Probleme mehr. 😉

    Es sei denn, eine Platte geht kaputt...



  • Tachyon schrieb:

    Fellhuhn schrieb:

    Nimm vier Platten im RAID-0-Verbund und du hast damit keine Probleme mehr. 😉

    Es sei denn, eine Platte geht kaputt...

    Who cares? Das Problem hast auch bei nur einer Platte. Oder einer SSD. Backups sind immer sinnig. 😉



  • Fellhuhn schrieb:

    Tachyon schrieb:

    Fellhuhn schrieb:

    Nimm vier Platten im RAID-0-Verbund und du hast damit keine Probleme mehr. 😉

    Es sei denn, eine Platte geht kaputt...

    Who cares? Das Problem hast auch bei nur einer Platte. Oder einer SSD. Backups sind immer sinnig. 😉

    Naja, das Risiko vervierfacht sich...



  • gibts da keine schlauen Tricks wie man das Codemäßig bissl beschleunigen kann?

    Irgendwelche trickserein zwischen HD und RAM? ... gar nix??



  • Tachyon schrieb:

    Fellhuhn schrieb:

    Tachyon schrieb:

    Fellhuhn schrieb:

    Nimm vier Platten im RAID-0-Verbund und du hast damit keine Probleme mehr. 😉

    Es sei denn, eine Platte geht kaputt...

    Who cares? Das Problem hast auch bei nur einer Platte. Oder einer SSD. Backups sind immer sinnig. 😉

    Naja, das Risiko vervierfacht sich...

    Was aber ja nicht heißt das viermal so schnell ein Fehler auftritt. Wenn man dann aber die Arbeit in einem Viertel der Zeit schafft ist das schon lohnenswert. 🙂
    Und noch ärgerlicher ist es mit nur einer Platte langsam zu arbeiten und trotzdem seine Daten zu verlieren. 😉

    Sonst halt RAID-5. Nicht ganz so fix aber sicherer.



  • Festplattenzugriffe sind nunmal langsam, diese solltest du so weit wie möglich vermeiden. Die einzige Möglichkeit es etwas zu beschleunigen ist größere Blöcke gleichzeitig zu lesen, anstatt z.B. Zeichen für Zeichen einzulesen. Aber auch das hilft nur wenig.



  • Ohne Garantie:
    Du könntest ja mal einen Test bauen, der per CreateFileMapping/ViewMapOfFile den Dateiinhalt direkt in den Speicher einblendet und die Daten von dort abholt. Vielleicht bringt das ein wenig Performance.



  • Du könntest zuerst die Dateien am Stück in 4 Strings einlesen. Dann rennen 4 Threads durch die Strings und füllen jeweils eine eigene std::list.
    Wenn die Threads fertig sind, werden die lists zusammengefügt.

    global_list.splice(global_list.end(), thread1.list);
    global_list.splice(global_list.end(), thread2.list);
    ...
    


  • Ok vielen Dank!

    Die Idee mit dem am stück einlesen klingt verlockend.
    Was ist die schnellste Variante um mit C++ eine ASCII Datei in den RAM zu schieben?



  • Vielleicht gibts schnellere Speziallösungen, aber ich mach das in etwa so

    std::string read_file(const char * file)
    {
    	std::ifstream ifs(file);
    	if (ifs.good())
    	{
    		ifs.seekg (0, std::ios::end);
    		size_t length = ifs.tellg();
    		ifs.seekg (0, std::ios::beg);
    
    		std::vector<char> buffer(length+1);
    		ifs.read (&buffer[0], length);
    		buffer[length] = 0;
    		return &buffer[0];
    	}
    	throw std::runtime_error("file ist doof");
    }
    


  • Ich denke schon, dass die Win32 API da mit den Filemappings schneller sein könnte, weil sie näher am System arbeiten als die C++ Streams. Ist aber, wie gesagt, reine Vermutung.



  • DocShoe schrieb:

    Ich denke schon, dass die Win32 API da mit den Filemappings schneller sein könnte, weil sie näher am System arbeiten als die C++ Streams.

    Zumindest vor einigen Jahren war das auch definitiv so (Und nicht nur um wenige Prozentpunkte).



  • Gilt das auch für ein einmaliges Einlesen? Ich benutze in einem Projekt gemappte Files (aus boost::interprocess), um in einer riesigen Datei viel drin rumzulesen, das ist tatsächlich sehr schnell. Aber nur um die Datei einmal einzulesen?



  • brotbernd schrieb:

    Gilt das auch für ein einmaliges Einlesen?...

    Ich hatte es vor einigen Jahren vor allem für das einmalige Einlesen und analysieren benötigt (und gleichzeitig durfte der Speicherverbrauch nicht massiv ansteigen).


Anmelden zum Antworten