C++ Programmperformance steigern - Speichernutzung, Multithreading

Y0DA92

Lt. Junior Grade
Registriert
Juni 2007
Beiträge
481
Hallo alle Leute da Draußen!
Es geht um Zweierlei. Also alles der Reihenfolge nach. Ich suche nach einer Möglichkeit ein Programm, dass hauptsächlich "vergleicht", zu beschleunigen. Es gibt viele Ansätze ich weiß, doch es interessieren mich eigentlich 2 Dinge genauer (wenn sonst noch Vorschläge sind gerne!).

Zuerst würde es mich interessieren wie ich dem Programm, dass maximal einen Stack von glaube ich 1MB hat, mehr "Speicher" zuweisen kann. Wie ist es möglich dem Compiler zu sagen: "Dieses Programm darf mehr Speicher nutzen"? Denn viele Anwendungen brauchen weit mehr. Oder denke ich vielleicht in die falsche Richtung und das Programm braucht einfach nur so wenig?

Ein ebenfalls sehr interessantes Thema ist vielleicht Multithreading, wobei da eine ausführliche Erklärung wahrscheinlich zu weit gehen würde. Vielleicht könnt ihr eure Meinung dazu äußern, ob er im allgemeinen Sinn machen würde dies zu implimentieren und wenn ja wie viel? Außerdem wären ein paar Links erwünscht ;).

Danke erstmal fürs lesen. Fragen, Anregungen und Antworten sind erwünscht...
 
Was vergleichst du denn und vor Allem wie?

Evtl. limitiert ja der Festplatten-IO weil du die Daten mehrmals liest anstatt sie im Speicher zu halten? Wenn das Programm bisher wenig Speicher benötigt dann liegt das halt daran, dass nicht viele Daten im Speicher gehalten wird und somit am Code bzw. den verarbeiteten Daten.

Multithreading hilft nur vernünftig wenn das Problem auch aufteilbar/parallelisierbar ist. Das hängt auch wiederum von der genauen Fragestellung ab. Im Idealfall kann man dann so viele Threads laufen lassen wie es CPU-Cores gibt (bzw. CPU-Threads wegen Hyperthreading) und verx-facht dann die Performance (ok, bisschen Overhead hat man meist).
Überlegbar wäre natürlich auch ob evtl. CUDA was bringen würde aber das macht natürlich nur abhängig vom genauen Szenario Sinn.

Generell ist natürlich auch zu sagen, dass man immer nur Sachen Optimieren sollte bei denen die Laufzeit auch wirklich kritisch ist. Hast du denn ein konkretes Performanceziel das einzuhalten ist?
 
Was vergleichst du denn?

Wieso machst du dir sorgen um den Stack? Ist dein Vergleich rekursiv implementiert? Was auch immer: Die Frage nach der Stackgröße ist implementierungsabhängig, hängt also davon ab, welchen C++-Compiler du verwendest.

Du tust sicher gut daran, mal grob zu zeigen, was dein Programm wie tut und welche Typen du für die Daten verwendest. Ansonsten ist keine deiner Frage konkret zu beantworten.
 
Ich würd die Software mal durch einen Profiler laufen lassen. Da sieht man gut Flaschenhälse.
Wenn Die Laufzeit des Programms zu >90% für eine einzige Funktion verbraucht wird, weißt
du auf jeden Fall, dass auch kleine Verbesserungen an genau der Stelle einiges an Performance
bringen.

So habe ich mal eine MD5 Implementierung sehr stark beschleunigt. Es gab eine kleine Funktion,
die lief aber fast 100% der Zeit, weil sie sehr sehr oft aufgerufen wurde. Schon kleine optimierungen
an der einen Funktion haben das Programm massiv beschleunigt.
 
mensch183 schrieb:
Wieso machst du dir sorgen um den Stack? Ist dein Vergleich rekursiv implementiert? Was auch immer: Die Frage nach der Stackgröße ist implementierungsabhängig, hängt also davon ab, welchen C++-Compiler du verwendest..

In erster Line hängt das vom Betriebssystem ab, und nicht etwa vom Compiler.

Ein Stack ist grundsätzlich nur von geringer Größe, und das hat auch seine Gründe. Wenn du mehr Speicher benötigst, dann verwende den Heap.
 
Also erstmal danke für die Antworten! Hier ist dann auch gleich mal der Hauptteil meines Programmes. (Hoffe es ist alles drinne, hab es ein wenig gekürzt)

Code:
int main(int argc, char *argv[]) {

	struct stat attributS,attributB;
	int i,j,gleiche=0,neuTemp=0,temp=0,clusterAnz=10;
	FILE *sFile, *bFile;

	if(stat(argv[1], &attributS) || stat(argv[2], &attributB) == -1) {
		cerr << "Fehler bei stat.\n";
		return EXIT_FAILURE;
    }

	vector<unsigned char> save(attributS.st_size);
	vector<unsigned char> buffer(attributS.st_size);
	vector<int> cluster(clusterAnz);

	for(i=0; i<clusterAnz; i++)
		cluster[i]=0;

	if((sFile=fopen(argv[1],"r")) == NULL) {
		cerr << "Konnte die Save-Datei (" << argv[1] << ") nicht \x84 \bffnen!\n";
		return EXIT_FAILURE;
	}

	if((bFile=fopen(argv[2],"r")) == NULL) {
		cerr << "Konnte die Buffer-Datei (" << argv[2] << ") nicht \x84 \bffnen!\n";
		return EXIT_FAILURE;
	}

	for(i=0; i<attributS.st_size; i++){
		save[i] = getc(sFile);
		buffer[i] = getc(bFile);
	}

	for(i=0; i<=(attributB.st_size-attributS.st_size); i++){
		for(j=0; j<attributS.st_size; j++){
			if(save[j]==buffer[(j+i)%(attributS.st_size)] && gleiche < 8)
				gleiche++;
			else {
				cluster[gleiche]++;
				gleiche=0;
			}
		}
		if(gleiche>3) {
			cluster[gleiche]++;
		}
		gleiche = 0;

		buffer[i%attributS.st_size]=getc(bFile);
	}

	cout << "\n\n\n= = = = = E r g e b n i s s e = = = = =\n\n";
	for(i=0; i<clusterAnz; i++){
		if(cluster[i] != 0)
			cout << cluster[i] << " Cluster der Laenge " << i << " gefunden.\n";
	}

	return EXIT_SUCCESS;
}

Funktion: Im Grunde genommen geht es darum, dass in der ersten Textdatei und der zweiten Textdatei (Argumente) identische Passagen bzw. Wörter gesucht werden. Diese identischen Teile nennt man dann Cluster.

Generell ist natürlich auch zu sagen, dass man immer nur Sachen Optimieren sollte bei denen die Laufzeit auch wirklich kritisch ist. Hast du denn ein konkretes Performanceziel das einzuhalten ist?

Ja und zwar brauch dieses Programm für die besagt Funktion etwa 1min für eine 30KB Datei und eine 100KB Datei. Am Ende sollen aber für das erste Argument ca. 1MB Datein verwendet werden und fürs 2. ca. 100MB.

Wieso machst du dir sorgen um den Stack?

Hier auch das "Problem" des Stacks. Da die erste Datei komplett eingelesen wird benötige ich soviel Speicher und was mich irritiert ist einfach, dass das Programm (im Taskmanager abgelesen) nur maginal viel Speicher nutz, obwohl Virenprogramme, die wohl auch sehr viel Vergleichen viel mehr Speicher nutzen.

Ein Stack ist grundsätzlich nur von geringer Größe, und das hat auch seine Gründe. Wenn du mehr Speicher benötigst, dann verwende den Heap.

Aber dann nutze ich wohl einen falschen Ansatz ;).

Multithreading hilft nur vernünftig wenn das Problem auch aufteilbar/parallelisierbar ist. Das hängt auch wiederum von der genauen Fragestellung ab.

Meine Idee wäre, da das 2.Argument, also die Datei in der identische Teile zur 1. Datei gesucht werden, hinterher aus mehreren Datein besteht, dass heißt ich suche später in sagen wir mal 20 Datein identische Teile von einer Datei, dass ich da per Multithreading die Datein pro Kern auf gleiche Teile überprüfen lasse.
Wenn man das nicht versteht, was ich da gerade geschrieben habe, kein Wunder ^^.

Ich würd die Software mal durch einen Profiler laufen lassen. Da sieht man gut Flaschenhälse.
Wenn Die Laufzeit des Programms zu >90% für eine einzige Funktion verbraucht wird, weißt
du auf jeden Fall, dass auch kleine Verbesserungen an genau der Stelle einiges an Performance
bringen.

Also als IDE benutze ich Eclipse gibts da vllt ein Add-On oder kannst du mir sonst was empfehlen?

Dann noch eine Frage. Benutze ich zurzeit eine performante Einleseart oder eher nicht? Meine Idee war auch schon das "einlesen", sprich Zwischenspeichern, per se zu entfernen.


Oke langer Text. Bestimmt ein paar Fehler und Sachen, die kein Mensch versteht, aber das wars erstmal von mir...:)
 
Mehrere Punkte. :)

Eclipse als C++-IDE ist imho PITA. ;) Eher Netbeans oder Code::Blocks oder einfach vim. ^^

Das Einlesen via getc ist brutal langsam. Da du eh immer einzelne Buchstaben speicherst, solltest du dir blockweises Lesen anschauen.

Die doppelte Schleife ist kombiniert mit dem Zugriff auf 3 Arrays dieser Größe ist ein Cache-Killer. Sprich, der Prozessor ist hauptsächlich damit beschäftigt, Daten aus dem vergleichsweise schneckenlangsamen RAM in den Prozessorcache zu nudeln. Aber - keine Ratespielchen machen, sondern eine Annahme durch einen Profiler verifizieren.
Da du stat benutzt, nehme ich mal an, du bist unter Linux? Dann könntest du die Valgrind-Suite - speziell Cachegrind - benutzen und das ganze dann mit KCacheGrind visualisieren. www.valgrind.org

HTH

P.S.: Prinzipiell ist das Problem parallelisierbar. So wie es dem ersten Anschein nach klingt sogar saugut parallelisierbar. Nuuuuur - ob sich dieser Aufwand lohnt, ist die Frage. Da du danach fragst, gehe ich davon aus, dass du in diesem Bereich wenig Erfahrung hast. Und da kann ich dir nur raten: Finger weg, wenn es nicht gaaanz unbedingt sein muss. Erstmal schauen, welche Performance man so rauskitzelt. Wenn das Programm mit 1MB vs. 100MB nur ein paar Sekunden läuft, wär's den Aufwand echt nicht wert.

Edit: Gerade den File-Access in der Schleife gesehen. Weg damit, das bremst unwahrscheinlich. Lieber alles brutal in den RAM prügeln. 100 MB tun heutzutage echt nimmer weh.
Edit2: Mach das Edit mal als erstes und schau auf die Performance. Erst wenn es nötig ist, mach weiter. Wenn das schon reicht, bist du fertig. ;)
 
Zuletzt bearbeitet:
Eclipse als C++-IDE ist imho PITA. Eher Netbeans oder Code::Blocks oder einfach vim.

Hat das fundierte Gründe oder ist das einfach deine persönliche Meinung? Sonst würde ich nämlich wechseln.

Das Einlesen via getc ist brutal langsam. Da du eh immer einzelne Buchstaben speicherst, solltest du dir blockweises Lesen anschauen.

Aber am Ende im Programm lesen ich Buchstabenweise ein, geht das dann immer noch? Kannste mir vielleicht mal nen Link geben?

Die doppelte Schleife ist kombiniert mit dem Zugriff auf 3 Arrays dieser Größe ist ein Cache-Killer. Sprich, der Prozessor ist hauptsächlich damit beschäftigt, Daten aus dem vergleichsweise schneckenlangsamen RAM in den Prozessorcache zu nudeln. Aber - keine Ratespielchen machen, sondern eine Annahme durch einen Profiler verifizieren.
Da du stat benutzt, nehme ich mal an, du bist unter Linux? Dann könntest du die Valgrind-Suite - speziell Cachegrind - benutzen und das ganze dann mit KCacheGrind visualisieren. www.valgrind.org

Nein nicht mehr. Bin bei Windows 7. Kennst du da auch nen guten?

P.S.: Prinzipiell ist das Problem parallelisierbar. So wie es dem ersten Anschein nach klingt sogar saugut parallelisierbar. Nuuuuur - ob sich dieser Aufwand lohnt, ist die Frage. Da du danach fragst, gehe ich davon aus, dass du in diesem Bereich wenig Erfahrung hast. Und da kann ich dir nur raten: Finger weg, wenn es nicht gaaanz unbedingt sein muss. Erstmal schauen, welche Performance man so rauskitzelt. Wenn das Programm mit 1MB vs. 100MB nur ein paar Sekunden läuft, wär's den Aufwand echt nicht wert.

Genau das glaube ich auch. Meinst du das mit den paar Sekunden ist realistisch. Das wäre perfekt!

Edit: Gerade den File-Access in der Schleife gesehen. Weg damit, das bremst unwahrscheinlich. Lieber alles brutal in den RAM prügeln. 100 MB tun heutzutage echt nimmer weh.

Wie genau meinst du das mit dem Prügeln? Denn du hast Recht:

gehe ich davon aus, dass du in diesem Bereich wenig Erfahrung hast



Aber vielen Dank erstmal für die vielen hilfreichen Tipps!!!
 
Y0DA92 schrieb:
Hat das fundierte Gründe oder ist das einfach deine persönliche Meinung? Sonst würde ich nämlich wechseln.
Vor allem persönlich - ich finde Eclipse C++-technisch total umständlich und das Schneckentempo von dem Ding treibt mich regelmäßig in den Wahnsinn. Aber das muss man letzten Endes selber wissen. :)

Aber am Ende im Programm lesen ich Buchstabenweise ein, geht das dann immer noch? Kannste mir vielleicht mal nen Link geben?
Du könntest z.B. fread nehmen: http://www.cppreference.com/wiki/io/c/fread
Das fgetc in der Schleife muss unbedingt da raus.

Nein nicht mehr. Bin bei Windows 7. Kennst du da auch nen guten?
Spontan leider nix kostenloses.

Genau das glaube ich auch. Meinst du das mit den paar Sekunden ist realistisch. Das wäre perfekt!
Naja, das wird sich dann zeigen. Das war eher verdeutlichend als realistisch gemeint. Sorry, wenn das unklar war.

Wie genau meinst du das mit dem Prügeln? Denn du hast Recht:
Einfach beide Dateien vollständig im RAM (sprich in den Vectoren) ablegen.

Gerade mal ein klein wenig genauer geschaut - der Algorithmus ist ineffektiv. Wenn die minimale Clusterlänge 3 ist, kann man mit einer "Sprungtabelle" arbeiten.

Beispieltext:
"super"

Du schaust im zweiten Array direkt auf Stelle 5 - ist hier kein r, kann "super" an den 4 Stellen davor nicht gestanden haben, sprich man macht an Stelle 10 weiter. Komplizierter wird das ganze, wenn Buchstaben in einem "Wort" mehrfach vorkommen. Dann muss man für jeden gefundenen Buchstaben schauen, wie weit man weiterspringen kann. Hier solltest du dich mal ein wenig nach effizienten Suchalgorithmen umschauen. Natürlich ist das für deinen Anwendungsfall wesentlich komplizierter, aber hier sollte es bereits gute Algorithmen geben, ohne dass man das Rad neu erfindet. Verstehen dieser Algorithmen sollte dann natürlich schon sein.

Ich hoffe, du hast die Edits in meinem vorherigen Post gesehen? :) Bau zuerst das File-Lesen in der Schleife aus. Dann könntest du dir evtl. einen besseren Algorithmus überlegen. Erst dann würde ich mich an die "advanced"-Sachen machen - zuerst Cache-Optimierung (evtl. kombinierbar mit Memory Mapped Files) und dann notfalls, wenn es unbedingt sein muss, Multithreading.
 
Zuletzt bearbeitet:
Die Schleife kannst du z.B. mit OpenMP recht leicht parallelisieren. Ich glaube aber nicht, dass dir das viel bringt. Zunächsteinmal limitiert hier sicherlich der Dateizugriff. Den müsstest du ohnehin anders machen, sprich entweder vorher puffern oder zumindest kritische Abschnitte, damit nicht von zwei Threads gelesen wird.
 
Einfach beide Dateien vollständig im RAM (sprich in den Vectoren) ablegen.

Also bei Arrays ging das nicht (man konnte die nicht komplett einlesen), mit Vektoren probiere ich das mal aus.

Edit:Ok das geht und es ist auch schon ein wenig flotter! Für heute kann ich den Rest leider nicht mehr ausprobieren. Morgen implementier ich alles andere mal und melde mich dann. Danke nochmal für die ganzen nützlichen Dinge!
 
Zuletzt bearbeitet:
Also bei Arrays ging das nicht (man konnte die nicht komplett einlesen)
Wie meinst du das? Mit fread müsste man die Dateien problemlos in ein Array schieben können (evtl. in Häppchen von ein paar kb einlesen wenns sonst Probleme gibt). Und da du scheinbar bfile zweimal brauchst kannst du dir das Array am Ende mittels memcpy in ein zweites gleicher Größe duplizieren.
 
Also wenn deine Dateien nicht riesig groß sind, dann solltest du diese schon komplett lesen können.

1. Dateigröße ermitteln
2. Buffer anlegen (malloc, etc)
3. Datei einlesen

Sollten deine Dateien wirklich recht groß sein, kannst du immer noch einen Puffer benutzen, in den du liest.
 
dein einziges problem ist der algorithmus, der ist echt mega-mies!
tip: dynamische programmierung!

ich garantiere dir einen enormen zuwachs an geschwindigkeit ohne tricksen zu müssen.
der speedup von besseren algos/datenstrukturen ist idR wesentlich höher.
Ergänzung ()

add:
http://de.wikipedia.org/wiki/Needleman-Wunsch-Algorithmus

einfaches problem der bioinformatik!
informier dich mal nach globalen und lokalen alignments.
garantiert in O(n*m). (n,m länge der dateien)
 
Zuletzt bearbeitet von einem Moderator:
Dieser verlinkte Algorithmus kriegt doch ziemlich schnell Probleme mit dem RAM oder sehe ich das falsch? Außerdem wird ja nur ein Score errechnet, der Threadersteller will aber die Übereinstimmungnen auch angezeigt bekommen.

Nichtsdestotrotz hast du grundsätzlich recht, dass man auch Optimierungen am bestehenden Algorithmus vornehmen kann wobei erstmal die IO-Sache behoben werden sollte und dann überprüft inwiefern die Performance vielleicht schon reicht oder nicht.

Ich hätte auch eine konkrete Optimierungsidee: Das kleinere File ist ja nur 1 MB groß. Insofern könnte man sich hier Trigramme (oder evtl. auch längere Konstrukte) in einer Hashmap abspeichern wobei der in der Hashmap gespeicherte Key das Trigramm und der Value ein Array oder eine LinkedList ist welche auf Stellen verweist wo das Trigramm im Text vorkommt. Findet man das Trigramm in der Hashmap nicht (was wesentlich schneller gehen sollte als 1MB zu durchsuchen!), so braucht man nicht weitersuchen, ansonsten muss man nur von allen gespeicherten Einstiegspunkten aus weitersuchen. Somit müsste man von O(n*m) auf O(n) kommen.

Alternativ könnte man auch Tries verwenden was sogar noch effizienter sein könnte. Denn zumindest im obigen Code sieht es so aus als ob nur Textteile mit einer Länge bis maximal 8 Stellen verglichen werden sollen. Man könnte also aus der kleineren Datei einen vollständigen Baum aufbauen mit Maximallänge 8 und direkt durch einen Lookup in diesem Baum feststellen ob es eine Übereinstimmung gibt bzw. wie weit die Übereinstimmung ist.
 
der algo kriegt def keine ram-probleme, den benutzen wir hier für gigabytegroßes!
je nach scoringfunktion ist er GENAU was er braucht. diese cluster sind sog. lokale alignments
-> scoring funktion nehmen die NUR matching belohnt und gaps/mismatches hart bestraft, jedoch minimal 0 wird (immer frischer start).
beginnt nun eine passende sequenz wird dieser optimale weg hochgezählt bis sagen wir mal 20 und danach wieder genullt. ist die matrix gefüllt wird im sog. backtracking genau start und endpunkt der cluster ermittelt (wieder O(n*m)) und du hast das problem beweisbar perfekt und wesentlich schneller gelöst.
die geschichte mit dem scoring erlaubt zusätzlich noch feine abstufungen wie "fast der selbe text"....
mächtige sache also.
der lokale war der hier:
http://de.wikipedia.org/wiki/Smith-Waterman-Algorithmus

wäre besser gewesen gleich den zu verlinken, sorry.


die gehashte datenstruktur ist prinzipiell auch gut, ich denke da das optimum wäre ein suffix-tree.
 
Ich kannte den Algorithmus bisher nicht bin da aber sehr interessiert dran. Allerdings kapiere ich nicht so ganz wieso es dort keine RAM-Probleme gibt. Ich dachte nach dem Lesen des englischen Wikipedia-Artikels ( http://en.wikipedia.org/wiki/Smith–Waterman_algorithm ), dass man hier zunächst die gesamte Matrix aufbauen muss und dafür benötigt man n*m Bytes an Speicherplatz um die Scores zu speichern. Oder lässt sich das effizienter implementieren?
Im letzten Kapitel steht ja auch was von diversen optimierten Fassungen mit SSE2 usw., weißt du welche die schnellste frei verfügbare Implementierung ist?
 
man kann es speichermäßig durch irgendein plateu-prinzip nochmal stark einschränken, das weiß ich jetzt aus dem stehgreif nicht mehr. (im moment hab ich eher mit machine learning am hut...)
mit sse(2)-optimierungen, keine ahnung, von solchen architektursachen hab ich garkeine ahnung! denke da liegt der gewinn in der parallelausführung im kleinen (in der scoring-fkt einzelwerte), das ganze lässt sich im großen wegen der abhängigkeit der teilprobleme eigentlich garnicht parallelisieren. (siehe speedup bei gpu-computing)

schnelle freie implementierungen ka, schaum al was bei BLAST / FASTA genutzt wird (aus dem kontext her kenne ich die algos)
 
Zuletzt bearbeitet von einem Moderator:
BerniG schrieb:
Im letzten Kapitel steht ja auch was von diversen optimierten Fassungen mit SSE2 usw., weißt du welche die schnellste frei verfügbare Implementierung ist?

Ich kenne zwar weder den Algorithmus, noch weiß ich, ob es davon verfügbare Implementierungen gibt. Bei dem SSE Kapitel ist aber die Referenz mit angegeben, in der steht was sie gemacht haben. Im Wesentlichen werden 8 8-bit Vergleiche parallel durchgeführt (MMX hat 64-Bit-Register) und man hat es auf zwei Cores parallel laufen. Mit den jetzigen Prozessoren könnte noch mehr gehen, da die Register ja jetzt 128 Bit breit sind.
Ergänzung ()

Nachtrag: ich hab mich auf die Referenz 13 im Wiki bezogen. Unter der Referenz 4 steht ja bereits ein Artikel, wo die Implementierung mit SSE2 gemacht wurde
 
Vielen Dank für das rege Interesse, nur ist es für mich als (fortgeschrittener) Programmier-Anfänger schwer der Diskussion über Algorithmen zu folgen, auch wenn das wohl genau das ist was ich suche. Ich habe mir die Wikipediaartikel durchgelesen und nur kleine Teile verstanden.

Ich bin mir nicht sicher, ob das alle vor Augen haben, wenn ja tuts mir Leid, aber ich will alle gleichen Teile zweier Datei in "Byteschritten" haben. Das heisst ich vergleiche alle Bytes beider Datein einmal mit einander. Hier nochmal meine Lösung:
(Ich suche identische Teile mit 4 bis 8 "Bytes")

Code:
for(i=0; i<=(sizeB-sizeS); i++){
	for(j=0; j<sizeS; j++){
		if(save[j]==buffer[j + i] && gleiche < 8)
			gleiche++;
		else {
			if(gleiche>3) {
				cluster[gleiche]++;
				testkatalog.setzeCluster(i+j-gleiche,j-gleiche,gleiche);
			}
			gleiche=0;
		}
	}
	if(gleiche>3) {
		cluster[gleiche]++;
	}
		gleiche = 0;
	}
}


Das Einlesen der Datein habe ich nun auch komplett geändert. Ich bin mir nicht sicher ob es gut ist keine Vektoren mehr zu nutzen?

Code:
long sizeS, sizeB;
char * save, * buffer;

ifstream fileS (argv[1], ios::in|ios::binary|ios::ate);
ifstream fileB (argv[2], ios::in|ios::binary|ios::ate);

if(fileS.is_open() && fileB.is_open()) {

    sizeS = (long)fileS.tellg();
    sizeB = (long)fileB.tellg();
    save = new char [sizeS];
    buffer = new char [sizeB];
    fileS.seekg (0, ios::beg);
    fileB.seekg (0, ios::beg);
    fileS.read (save, sizeS);
    fileB.read (buffer, sizeB);
    fileS.close();
    fileB.close();
    cout << "\nDie Datein wurden erfolgreich eingelesen!\n";
}

Es tut mir Leid, aber ich kann der Informationsflut, die ihr mir bietet nicht ganz folgen. Ich bitte, wenn es euch nichts ausmacht vielleicht, die Algorithmen an meinem Beispiel zu verdeutlichen.
 
Zurück
Oben