[boost] Mutex will nicht so wie ich
-
Dravere schrieb:
Pikkolini schrieb:
..., dass Hyperthreading nicht wirklich was schneller macht sondern nur langsamer.
Woher hast du den Unsinn schon wieder?
Den Unsinn habe ich schon in vielen Foren gelesen, da viele Leute meinten, dass sich zwei Threads trotzdem noch ein Kern teilen müssen und so aufeinander warten müssen. Ob das stimmt keine Ahnung.
Und nun zum Programm. Ich verwende momentan keine Mutex und mit mehreren Threads greife ich auch nicht auf das gleiche zu. Hier mal mein Vollständiger Code:
// MyThread.h class MyThread { public: MyThread(int tid, int interval, int maxdiv); void startThread(void); std::vector<std::string> getValues(void); private: int tid; int interval; int maxdiv; std::vector<std::string> values; }; // MyThread.cpp MyThread::MyThread(int tid, int interval, int maxdiv) { this->tid = tid; this->interval = interval; this->maxdiv = maxdiv; }; void MyThread::startThread(void) { for (int i = 0; i < interval * tid; i++) { for (int j = 1; j <= maxdiv; j++) { srand(i); int v = rand() % j; std::stringstream ss; ss << v << "\n"; values.push_back(ss.str()); } } }; std::vector<std::string> MyThread::getValues(void) { return values; }; // Random.cpp int _tmain(int argc, _TCHAR* argv[]) { if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) { std::cout << "Priorität erhöhen fehlgeschlagen" << std::endl; getchar(); return 0; } SYSTEM_INFO sysinfo; GetNativeSystemInfo(&sysinfo); int cores = sysinfo.dwNumberOfProcessors; std::cout << "Anzahl der Threads: " << cores << std::endl; std::cin >> cores; // nur Testzwecke std::cout << "Minimale Systemzeit" << std::endl; int mintime; std::cin >> mintime; std::cout << "Maximale Systemzeit" << std::endl; int maxtime; std::cin >> maxtime; std::cout << "Maximale Division (keine 0)" << std::endl; int maxdiv; std::cin >> maxdiv; if (maxdiv < 1) maxdiv = 1; int delta = maxtime - mintime; int interval = delta / cores; std::cout << "Interval: " << interval << std::endl; std::vector<std::string> values; boost::thread_group threads; timer time; time.init(); time.begin(); for(int i = 0; i < cores; ++i){ MyThread myThread(i, interval, maxdiv); threads.create_thread(boost::bind(&MyThread::startThread,myThread)); } threads.join_all(); double deltatime = time.stop(); std::cout << deltatime << std::endl; std::cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); getchar(); return 0; }Die Funktion getValues steht da jetzt einfach so, aber ich brauch sie nicht wirklich.
Dravere schrieb:
Ich stelle wieder mal fest, du machst völlig seltsame Messungen. Profiling, erst recht Profiling über Threads und Performanceoptimierungen über Threads ist ein sehr fortgeschrittenes Thema. Das was du hier probierst ist blanker Unsinn.
Wieso seltsame Messungen? Ich messe nur die Zeit, und darauf kommt es in meinem Programm ja an.
Dravere schrieb:
Erstaunt mich irgendwie nicht. Einfach nur ein paar parallel laufende Threads einzurichten, heisst meistens nicht, dass das Programm schneller wird. Das ist ein grosser Irrtum von vielen.
Anscheindend gehör ich zu den vielen

Aber was gehört dann denn noch zu Performanceoptimierung dazu?Dravere schrieb:
Das was du hier probierst ist blanker Unsinn.
Wieso ist Parallelisierung zu probieren blanker unsinn?
-
Pikkolini schrieb:
Dravere schrieb:
Pikkolini schrieb:
..., dass Hyperthreading nicht wirklich was schneller macht sondern nur langsamer.
Woher hast du den Unsinn schon wieder?
Den Unsinn habe ich schon in vielen Foren gelesen, da viele Leute meinten, dass sich zwei Threads trotzdem noch ein Kern teilen müssen und so aufeinander warten müssen. Ob das stimmt keine Ahnung.
Es stimmt nicht. Die Idee hinter Hyperthreading ist folgende. Laufen zwei Threads und der eine wartet muss auf Daten aus dem Hauptspeicher warten (der ist langsam), so kann der andere laufen und Berechnungen durchführen. Die zwei Threads laufen also nie gleichzeitig, aber trotzdem kann es ein Programm schneller machen.
Pikkolini schrieb:
Und nun zum Programm. Ich verwende momentan keine Mutex und mit mehreren Threads greife ich auch nicht auf das gleiche zu.
values.push_back(ss.str());Doch tust du. Genau an der obigen stelle. Und genau da kann eine Menge schief gehen. Mit großer Wahrscheinlichkeit steht, wenn alle Threads fertig sind, nicht das im Vektor, was vorher rein geschrieben wurde.
Und noch eine Stelle
int v = rand() % j;Die Funktion
randist nicht thread-save. Wenn du aus mehreren Threads die Funktionrandaufrufst, zerstörst du die internen Strukturen der Funktion.Pikkolini schrieb:
Dravere schrieb:
Erstaunt mich irgendwie nicht. Einfach nur ein paar parallel laufende Threads einzurichten, heisst meistens nicht, dass das Programm schneller wird. Das ist ein grosser Irrtum von vielen.
Anscheindend gehör ich zu den vielen

Aber was gehört dann denn noch zu Performanceoptimierung dazu?Du kannst mehrere Threads schon verwenden, um ein Programm schneller zu machen. Mal abgesehen von den Fehlern oben, wird dein Programm nicht schneller durch mehrere Threads, weil der Hauptspeicher nicht schneller wird. Und der ist wahrscheinlich der Flaschenhals bei der Anwendung.
Je nach dem, was du für einen Prozessor hast, können die dauernden Cache-Synchronisationen deinen Code auch noch stark ausbremsen.
-
ProgChild schrieb:
Pikkolini schrieb:
Und nun zum Programm. Ich verwende momentan keine Mutex und mit mehreren Threads greife ich auch nicht auf das gleiche zu.
values.push_back(ss.str());Doch tust du. Genau an der obigen stelle. Und genau da kann eine Menge schief gehen. Mit großer Wahrscheinlichkeit steht, wenn alle Threads fertig sind, nicht das im Vektor, was vorher rein geschrieben wurde.
Jeder Thread hat einen eigenen Vektor. Deine Aussage ist daher (wie ich denke) falsch.
ProgChild schrieb:
Und noch eine Stelle
int v = rand() % j;Die Funktion
randist nicht thread-save. Wenn du aus mehreren Threads die Funktionrandaufrufst, zerstörst du die internen Strukturen der Funktion.
Genau... Hier ist der kritische Punkt...Wenn du folgende Zeile
for (int i = 0; i < interval * tid; i++)änderst in
for (int i = 0; i < interval * tid; i+=tid)dann wird mein Programm nur (etwa) linear langsamer, weil die zu berechnenden Daten ebenfalls linear wachsen.
Nach der Synchronisierung des Zufallszahlengenerators wird es jedoch wohl etwas anders aussehen.
-
ProgChild schrieb:
Pikkolini schrieb:
Dravere schrieb:
Pikkolini schrieb:
..., dass Hyperthreading nicht wirklich was schneller macht sondern nur langsamer.
Woher hast du den Unsinn schon wieder?
Den Unsinn habe ich schon in vielen Foren gelesen, da viele Leute meinten, dass sich zwei Threads trotzdem noch ein Kern teilen müssen und so aufeinander warten müssen. Ob das stimmt keine Ahnung.
Es stimmt nicht. Die Idee hinter Hyperthreading ist folgende. Laufen zwei Threads und der eine wartet muss auf Daten aus dem Hauptspeicher warten (der ist langsam), so kann der andere laufen und Berechnungen durchführen. Die zwei Threads laufen also nie gleichzeitig, aber trotzdem kann es ein Programm schneller machen.
Ok danke. Würde es dann in meinem Programm Sinn machen oder nicht?
ProgChild schrieb:
Pikkolini schrieb:
Und nun zum Programm. Ich verwende momentan keine Mutex und mit mehreren Threads greife ich auch nicht auf das gleiche zu.
values.push_back(ss.str());Doch tust du. Genau an der obigen stelle. Und genau da kann eine Menge schief gehen. Mit großer Wahrscheinlichkeit steht, wenn alle Threads fertig sind, nicht das im Vektor, was vorher rein geschrieben wurde.
Wird in der for-Schleife nicht für jeden Thread ein eigenes Klassenobjekt erstellt? Wenn die for-Schleife acht mal durchläuft, werden doch auch acht unterschiedliche Objekte erstellt oder nicht?
ProgChild schrieb:
Und noch eine Stelle
int v = rand() % j;Die Funktion
randist nicht thread-save. Wenn du aus mehreren Threads die Funktionrandaufrufst, zerstörst du die internen Strukturen der Funktion.Gibts denn eine Alternative dafür? rand_s suche ich nicht, da das die eigentlich Idee meines Programm zerstören würde.
ProgChild schrieb:
Pikkolini schrieb:
Dravere schrieb:
Erstaunt mich irgendwie nicht. Einfach nur ein paar parallel laufende Threads einzurichten, heisst meistens nicht, dass das Programm schneller wird. Das ist ein grosser Irrtum von vielen.
Anscheinend gehör ich zu den vielen

Aber was gehört dann denn noch zu Performanceoptimierung dazu?Du kannst mehrere Threads schon verwenden, um ein Programm schneller zu machen. Mal abgesehen von den Fehlern oben, wird dein Programm nicht schneller durch mehrere Threads, weil der Hauptspeicher nicht schneller wird. Und der ist wahrscheinlich der Flaschenhals bei der Anwendung.
Je nach dem, was du für einen Prozessor hast, können die dauernden Cache-Synchronisationen deinen Code auch noch stark ausbremsen.
Das der Hauptspeicher nicht schneller wird ist klar. Aber wird der schon der Flaschenhals, wenn ich auch nur eine Variable schreiben will?
-
XSpille schrieb:
Wenn du folgende Zeile
for (int i = 0; i < interval * tid; i++)änderst in
for (int i = 0; i < interval * tid; i+=tid)dann wird mein Programm nur (etwa) linear langsamer, weil die zu berechnenden Daten ebenfalls linear wachsen.
Ich Idiot

Diese Zeile:for (int i = 0; i < interval * tid; i++)muss natürlich so heißen:
for (int i = interval * tid - interval; i < interval * tid; i++)Ansonsten muss ja jeder neue Thread zu dem alten, schon berechneten, nochmehr rechnen, was ja ziemlich sinnlos ist. DIe Threads sollen sich die Arbeit ja teilen. Nach der Änderung ist mein Programm mit mehreren Threads direkt mal um einiges schneller.
Jetzt bleibt eigentlich nurnoch das Problem, dass rand() nicht Threadsicher ist...
-
Pikkolini schrieb:
Jetzt bleibt eigentlich nurnoch das Problem, dass rand() nicht Threadsicher ist...
Stichwort: rand_r
-
rand_r klingt in der Theorie zwar ziemlich vielversprechend, aber laut google muss ich dazu die cstdlib einbinden. Doch dort ist rand_r nicht definiert...
-
Warum verwendest du nicht konsequent boost?
Du brauchst dann natürlich ein
boost::mt19937 gen;mit unterschiedlichen seeds pro Thread.
-
Weil ich alle random Zahlen mit verschiedenen Seeds und Divisionen auflisten will. rand_s() oder boost helfen mir da nicht weiter und rand_r() scheint nur in der Theorie zu existieren, da die C++ Referenz und die MSDN das auch nicht gelistet haben.
-
Pikkolini schrieb:
Weil ich alle random Zahlen mit verschiedenen Seeds und Divisionen auflisten will.
Dann betrachte ich das Problem mal theoretisch...
Du willst in verschiedenen Threads Zufallszahlen generieren, die basierend auf
einer globalen Information (seed & der letzten erzeugten Nummer?) arbeiten. Jeder
Zugriff auf die globale Information muss folglich synchronisiert werden.
(Ob explizit durch dich oder die Funktion, die du verwendest sei mal
nebensächlich.)
Ein anderer Thread kann folglich erst auf die globalen Informationen zugreifen,
wenn die neue Zufallszahl komplett berechnet ist. Danach wird sie nur noch an
deine gewünschten Grenzen angepaßt.
(Bitte korrigiert mich, falls die letzte erzeugte Zahl nicht relevant für
die Folgezahl ist)Jetzt muss also der Aufwand für die Synchronisierung mit dem Anpassen an
deinen gewünschten Bereich verglichen werden.
Als Tipp: Synchronisierung kann sehr teuer sein...Als Übung für verschiedene Threads ist das ok, in der Praxis ist es jedoch
ziemlich unvorteilhaft...EDIT: Wenn du jetzt jedem Thread einen anderen seed gibst, lohnt es sich
(evtl.) bis zur Anzahl der Kerne in deinem Rechner...
Du willst doch eh die Ergebnisse für verschiedene seeds berechnen.
-
Pikkolini schrieb:
Wieso seltsame Messungen? Ich messe nur die Zeit, und darauf kommt es in meinem Programm ja an.
Die Frage ist aber, ob die Messung auch stimmt? Und wann stimmt sie überhaupt? Und wenn sie nicht stimmt, woran ist sie gescheitert? Wenn man einfach so allgemein misst, kann man meistens so ziemlich wenig Rückschlüsse ziehen und somit keine Erkenntnisse gewinnen. Im allgemeinen stricken sich die Leute dann irgendwelche wilden Erklärungen zusammen, welche noch mit etwas Halbwissen gewürzt sind.
Pikkolini schrieb:
Anscheindend gehör ich zu den vielen

Aber was gehört dann denn noch zu Performanceoptimierung dazu?
Wieso ist Parallelisierung zu probieren blanker unsinn?Dein Vorgehen ist blanker Unsinn. Du versucht irgendwie wild etwas zu probieren und scheinst nicht viel Ahnung in dem Bereich zu haben. Das führt zu nichts. Wenn man Parallelisierung für Performanceoptimierungen verwenden möchte, muss man ganz gezielt vorgehen und genau wissen, was man tut.
Ich habe erst letztens ein schönes Beispiel für Performancoptimierung mit Parallelisierung gesehen. Ein schönes Beispiel war es auf zwei Arten, nämlich dass es zum einen schneller ablief, aber trotzdem nicht so wie gewünscht. Das Beispiel berechnete die Mandelbrot-Menge. Dabei wurden Abschnitte jeweils in Threads ausgelagert. Das ist auch wirklich etwas, was man sehr schön parallelisieren kann, denn die Berechnung braucht Zeit und ist unabhängig von den anderen zu berechnenden Teilen.
Die Erwartung war, dass mehr Threads bedeutet, dass es auch schneller abläuft, bis alle CPUs voll ausgelastet sind (war ein Multi-CPU-System/Server). Die Kurve war aber anders als erwartet. Zuerst gab es eine Beschleunigung, danach aber, obwohl die CPUs noch nicht voll ausgelastet waren, gab es eine deutliche Abflachung, zum Teil brauchte es sogar länger als mit weniger Threads. Und danach wurde es nochmals etwas schneller.
Die Vermutung für diesen Knick in der Kurve war, dass für gewisse Bereiche die Berechnung deutlich schneller ablief. Somit wurde eine grosse Zahl von Threads auf Bereiche losgelassen, welche gar nicht grosser Berechnung bedurften. Der Fehler war also, dass die Berechnungen gleichmässig auf die Threads verteilt wurden. Bei einer gewissen Anzahl von Threads wurden soviele Threads für nichts verbraten, dass sich das Starten von neuen Threads sehr negativ auf die benötigte Zeit ausgewirkt hat.Einfach parallelisieren bringt nicht immer etwas, weil die Parallelisierung auch Zeit benötigt. Und zwar nicht nur beim Starten von Threads, wogegen man mit Threadpools ein bisschen etwas unternehmen kann, sondern vor allem auch wenn man Bereiche vor parallelem Zugriff schützen muss. Zudem gibt es eben auch Begrenzungen in der Hardware. ProgChild hat da auch ein paar Dinge genannt. Und nicht zuletzt lassen sich viele Bereiche in einem Programm gar nicht sinnvoll parallelisieren oder zumindest nicht mit den heutigen Sprachmittel.
Wir haben übrigens sogar einen kurzen Artikel, welcher vor der unbedachten Parallelisierung warnt (zwar nicht unbedingt mit Threads): Der Dreisatz lügt
Grüssli
-
@XSpille
Welche globale Informationen?
Ganz zu Beginn werdem dem Thread ein paar globale Informationen zugewiesen, danach greift er aber nurnoch auf seine eigenen zu.Und mit dem Problem mit rand() und der Threadsicherheit. Nach den ganzen google Ergebnissen, die ich durchforstet habe, deute ich die Threadunsicherheit von rand() so, dass grob gesagt einfach in den verschiedenen Threads die gleichen Zahlen erzeugt werden. Aber wenn ich ich mit srand() vor jedem Aufruf von rand() benutze, sollte das Problem doch behoben sein.
Bitte korrigiert mich, wenn ich falsch liege.@Dravere
Also die Zeitmessung stimmt. Ich kann auch ohne Timer 0,0005 zwischen 10 Sekunden unterscheiden
Und zu dem blanken Unsinn, den ich angeblich veranstalte. Wie kann man genau wissen, wie man etwas tut wenn man es noch nie vorher gemacht hat? Oder konntest du direkt nach deiner Geburt perfekt programmieren?

Und nachdem ich meinen Logikfehler behoben habe, hatte ich sogar einen ziemlich deutlichen Performance Boost.
-
Pikkolini schrieb:
Also die Zeitmessung stimmt.
Woher weisst du, dass deine Messung stimmt? Woher weisst du, dass sie nicht von irgendetwas externen beeinflusst wurde? Wie genau läuft die Messung? usw. usf.
Nur weil Resultate korrekt aussehen, müssen sie nicht korrekt sein.Pikkolini schrieb:
Und zu dem blanken Unsinn, den ich angeblich veranstalte. Wie kann man genau wissen, wie man etwas tut wenn man es noch nie vorher gemacht hat? Oder konntest du direkt nach deiner Geburt perfekt programmieren?

Ich habe mich jedenfalls nicht an einen Editor gesetzt, dort reingeschrieben "Ich will ein Spiel haben", es dann angestarrt und mich darüber gewundert, dass ich noch kein Spiel vom Editor bekommen habe.
Oder anders gesagt: Bevor die Praxis kommt, muss man zuerst die Theorie lernen, sonst hast du keinen Schimmer, was du eigentlich machst oder machen musst.Grüssli
-
Pikkolini schrieb:
@XSpille
Welche globale Informationen?
Ganz zu Beginn werdem dem Thread ein paar globale Informationen zugewiesen, danach greift er aber nurnoch auf seine eigenen zu.Eine Zufallszahl errechnet sich aus einer (oder mehreren) zuvor errechneten
Zufallszahl(en). Jetzt brauch der
Generator Informationen, die den Zustand repräsentieren.
In dem Aufruf für die Erzeugung werden diese Informationen ausgelesen und
aktualisiert. In dem rand_r wird vermutlich(!!!) nur ein Mutex um das rand gemacht,
der gleichzeitigen Zugriff verhindert. Aber alle Threads greifen auf die
gleichen Informationen zu.Hier ist das Prinzip eines einfachen Zufallsgenerator erläutert:
http://www-i1.informatik.rwth-aachen.de/~algorithmus/Algorithmen/algo38/algo38.pdf
-
Dravere schrieb:
Pikkolini schrieb:
Also die Zeitmessung stimmt.
Woher weisst du, dass deine Messung stimmt? Woher weisst du, dass sie nicht von irgendetwas externen beeinflusst wurde? Wie genau läuft die Messung? usw. usf.
Nur weil Resultate korrekt aussehen, müssen sie nicht korrekt sein.1. Ich habe den timer, den ich benutze schon sehr oft benutzt und es kamen immer die Ergebnise, welche ich erwartet habe.
2. Interessiert es in diesem Fall niemanden, ob es jetzt 0,0005 oder 0,0006 Sekunden sind.
3. Kann ich auf die Uhr gucken und sagen, dass wen der Timer 10 Sekunden ausgibt, diese 10 Sekunden auch stimmen. Oder willst du jetzt auch noch anzweifeln, ob meine Uhren alle korrekt laufen, und mich mein Zeitgefühl vollkommen täuscht?
4. Was willst du damit eigentlich bezwecken? Das ist keine Zeitkritische Anwendung, wo es auf jede Millisekunde aufkommt. Also ist deine Kleinkrämerei ziemlich sinnlos.Dravere schrieb:
Pikkolini schrieb:
Und zu dem blanken Unsinn, den ich angeblich veranstalte. Wie kann man genau wissen, wie man etwas tut wenn man es noch nie vorher gemacht hat? Oder konntest du direkt nach deiner Geburt perfekt programmieren?

Ich habe mich jedenfalls nicht an einen Editor gesetzt, dort reingeschrieben "Ich will ein Spiel haben", es dann angestarrt und mich darüber gewundert, dass ich noch kein Spiel vom Editor bekommen habe.
Oder anders gesagt: Bevor die Praxis kommt, muss man zuerst die Theorie lernen, sonst hast du keinen Schimmer, was du eigentlich machst oder machen musst.Um es ganz kurz zu fassen: Hätte ich mich nicht vorher mit der Theorie befasst wüsste ich jetzt nicht das es boost gäbe, was Threads sind, wie ich diese überhaupt in mein Projekt einbinde etc.
Nur funktioniert eigentlich fast nie was neues direkt beim ersten Versuch. Aber aus seinen Fehler lernt man bekanntlich ja.
-
Pikkolini schrieb:
1. Ich habe den timer, den ich benutze schon sehr oft benutzt und es kamen immer die Ergebnise, welche ich erwartet habe.
Das sagt ja schon alles aus. Weil es deinen Erwartungen entspricht, war die Messung richtig. Doch das ist eben völlig falsch. Messungen können auch richtig sein, wenn sie deinen Erwartungen nicht entsprechen. Auch können deine Erwartungen falsch sein.
Pikkolini schrieb:
4. Was willst du damit eigentlich bezwecken? Das ist keine Zeitkritische Anwendung, wo es auf jede Millisekunde aufkommt. Also ist deine Kleinkrämerei ziemlich sinnlos.
Es geht mir darum, dass du falsche Annahmen triffst, weil du nicht korrekt misst/interpretierst. Du führst mit deinem Timer dein Programm auf deinem Computer aus und danach auf dem Laptop und weil es auf diesen beiden Systemen mit den Threads schneller lief, gehst du davon aus, dass es überall schneller laufen wird. Dabei kann es gut sein, dass es anderswo unter anderen Bedingungen langsamer laufen würde. Ich behaupte einfach, dass du zu wenig Wissen hast, um sinnvolle Messungen durchzuführen, bzw. deine Messungen nicht richtig interpretieren kannst.
Pikkolini schrieb:
Um es ganz kurz zu fassen: Hätte ich mich nicht vorher mit der Theorie befasst wüsste ich jetzt nicht das es boost gäbe, was Threads sind, wie ich diese überhaupt in mein Projekt einbinde etc.
Nur funktioniert eigentlich fast nie was neues direkt beim ersten Versuch. Aber aus seinen Fehler lernt man bekanntlich ja.Das Problem ist, dass du kein sinnvolles Profiling über Threads durchführen kannst mit deinem Grundlagenwissen über Threads. Dazu gehört viel mehr. Dadurch ignorierst du viele Fehlerquellen beim Messen und die Fehler fallen dir gar nicht auf.
Probier Threads zuerst einmal richtig anzuwenden, bevor du damit probierst die Performance zu verbessern. Man sollte wirklich sattelfest sein und die Threads verstehen (Betriebsystem und Hardware spezifisch), bevor man sich an Performanceoptimierungen durch Threads macht. Sonst rennst du nur in eine Falle nach der anderen und merkst es zum Teil nicht einmal.
Aber gut, ich will dich zu nichts drängen. Es ist alles wirklich nur als guten Raten zu verstehen. Profiling ist ein sehr komplexes Thema, welches viele am Anfang unterschätzen.
Grüssli
-
XSpille schrieb:
Jeder Thread hat einen eigenen Vektor. Deine Aussage ist daher (wie ich denke) falsch.
Ah ja... War gestern etwas in Eile. Mein Fehler...
Pikkolini schrieb:
Das der Hauptspeicher nicht schneller wird ist klar. Aber wird der schon der Flaschenhals, wenn ich auch nur eine Variable schreiben will?
DDR-400 hat eine Datenrate von
3.2 * 10^9Bytes pro Sekunde. Eine double Variable hat 8 Bytes. Ein moderner x86 kompatibler Prozessor kann pro Takt und pro Kern 2 Gleitkommaberechnungen durchführen. Gehen wir (der Einfachheit halber) von einem 3.2 GHz Prozessor aus, so kann der Prozessor 16 mal so schnell Gleitkommazahlen berechnen, wie er sie in den Speicher schreiben kann. DDR2-1066 schafft8.533 ^ 10^9Bytes pro Sekunde. Da ist der Prozessor immer noch um einiges schneller.Der Prozessor hat noch einen Cache. Der macht die Sache schneller. Wenn man aufpasst, dann ist das Problem nicht so groß. Wenn man nicht aufpasst, kann es sein, dass der Code durch den Cache langsamer läuft.
Um deine Frage zu beantworten: Falls die Berechnung trivial ist, dann wird der Speicher der Flaschenhals. Du musst auch bedenken: Du schreibst ja nicht nur eine Variable. Der Zustand der
randFunktion muss gesichert werden. Und einvector<T>::push_backhat auch einiges an Speicher zu verwalten.Pikkolini schrieb:
Und mit dem Problem mit rand() und der Threadsicherheit. Nach den ganzen google Ergebnissen, die ich durchforstet habe, deute ich die Threadunsicherheit von rand() so, dass grob gesagt einfach in den verschiedenen Threads die gleichen Zahlen erzeugt werden. Aber wenn ich ich mit srand() vor jedem Aufruf von rand() benutze, sollte das Problem doch behoben sein.
Bitte korrigiert mich, wenn ich falsch liege.Du liegst Falsch.
Mit welchem Parameter willst du denn
srandAufrufen? Macht keinen Sinn.Und selbst wenn: Wenn du den Aufruf von
randundsrandnicht in einen Mutex packst, dann rufen mehrere Threads gleichzeitigsrandmit verschiedenen seeds auf und überschreiben gegenseitig jeweils die Werte des anderen. Und wenn du dannrandaufrufst, dann kriegst du im schlimmsten Fall in allen Threads einen Wert vonrandzu einem seed, der eine Mischung aus den seeds der Verschiedenen Threads ist. Z.b. die ersten 2 Byte des ersten Threads und die letzten 2 Bytes des zweiten Threads. Aber in allen Threads den selben Wert.Wenn du aber einen Mutex verwendest, dann läuft dein Code wieder vollkommen seriell ab. D.h. er wird durch die Threads nur langsamer.
Und mal zu dem, vor dem dich die anderen warnen:
Du arbeitest mit Zufallszahlen. Du hast also keine Möglichkeit, überhaupt zu überprüfen, ob die Ergebnisse richtig sind.
Und Threads sind sehr böse. Da jetzt die Reihenfolge der Befehle nicht mehr fest steht, in der die Aktionen ausgeführt werden, kann es sein, dass ein Fehler nur ein einem von zehn Fällen zum Vorschein kommt. Das macht das Debuggen extrem schwierig.
Wenn du also nicht genau weißt, was du tust, wirst du Fehler in deine Programme bauen, die extrem schwer zu finden sind und vollkommen unerwartet auftreten. Und wenn du irgendwelche Berechnungen machst, wird es noch schlimmer. Weil du die Fehler nicht mal mehr siehst. Die Ergebnisse sind einfach hin und wieder mal falsch...
Also achte drauf, nur Funktionen zu verwenden, die als thread-safe ausgewiesen sind! Also z.B.
rand_r. Und schau dir ruhig noch ein wenig mehr Theorie zu der Materie an.