Multithreading, volatile, Cache usw.
-
wxSkip schrieb:
volatile heißt AFAIK zuallererst, dass der Compiler annehmen darf, dass sich eine Variable nicht spontan ändert.
Da fehlt ein "nicht" in dem Satz: nicht annehmen darf.
Oder anders gesagt: davon ausgehen muss, dass sich die Variable spontan ändern kann.
Oder nochmal anders gesagt: volatile Variablen sind per Definition "beobachtbar", d.h. sämtliche Stores/Fetches auf volatile Variablen müssen auch wirklich durchgeführt werden (und auch in der richtigen Reihenfolge).
-
@multicache
Vereinfacht kannst du dir vorstellen, dass nach dem Locken einer Mutex alle Daten neu vom RAM in den Cache geladen werden, und vor dem Freigeben einer Mutex werden alle geänderten Daten vom Cache ins RAM zurückgeschrieben. Und das gilt für alle Daten, volatile spielt diesbezüglich keine Rolle.Wenn du also sowas hast
LockMutex(); int data = g_gemeinsameVariableX; data = BerechneNeuenWert(data); g_gemeinsameVariableX = data; UnlockMutex();
dann muss das funktionieren.
Für die "Kurzfassung"LockMutex(); g_gemeinsameVariableX = BerechneNeuenWert(g_gemeinsameVariableX); UnlockMutex();
gilt natürlich das selbe.
-
hustbaer schrieb:
@multicache
Vereinfacht kannst du dir vorstellen, dass nach dem Locken einer Mutex alle Daten neu vom RAM in den Cache geladen werden, und vor dem Freigeben einer Mutex werden alle geänderten Daten vom Cache ins RAM zurückgeschrieben.Ist deswegen ein Mutex Lock so langsam?
-
multicache schrieb:
Ist deswegen ein Mutex Lock so langsam?
exakt.
//edit 1 Wort-Antwort und ich vertippe mich. Brauche mehr Kaffee
-
Ja und nein, kommt drauf an wie du es siehst.
-
warum müssen die daten denn vom cache in den ram?
volatile bezieht sich doch auf register <-> speicher, oder nicht?
ist der cache etwa prozess/thread spezifisch?
jenz
-
In modernen MultiCore-CPUs haben beide Kerne mindestens einen eigenen L1-Cache. Manchmal ist auch schon der L2 getrennt. In dem Fall muss der korrekte Wert im Ram stehen, damit der Cache der anderen CPU sich aktualisieren kann.
-
tatsache. ist ja ein ding.
ich sehe leider gerade den vorteil nicht.muss das dann wirklich per befehl angestoßen werden?
oder sind caches irgendwie verbunden um einen zugriff auf die selbe stelle zu bemerken?jenz
-
@jenz
Ja, Tatsache.
Wenn du nochmal freundlicher fragst, nimmt sich vielleicht jmd. die Zeit es dir zu erklären.
-
huch, unfreundlich?
mag mir jemand den vorteil von getrennten caches erklären?
-
tatsache. ist ja ein ding.
ich sehe leider gerade den vorteil nicht.War das etwa nicht schnippisch/verarschend gemeint?
Ich kenne keinen der "tatsache. ist ja ein ding." im Ernst sagt (und erst recht nicht schreibt), das ist immer verarsche.Der Vorteil ist dass getrennte Caches schneller sind. Sollte irgendwie logisch sein dass es schneller ist wenn jeder Core "seinen" Cache ganz für sich alleine hat.
Was die automatische Synchronisierung angeht: x86/AMD64 synchronisieren die Caches auch brav automatisch. Andere CPUs tun das nicht - u.a. weil es überhaupt nicht trivial ist das so hinzubekommen, dass es a) zuverlässig funktioniert und dabei b) nicht fürchterlich bremst. Und "nicht trivial" schlägt sich nicht nur in den Entwicklungskosten nieder, sondern auch in der Transistorzahl.
Im Endeffekt ist aber für 99.99% der Programmierer egal warum gewisse Dinge nicht garantiert sind. Viel wichtiger ist das Wissen dass sie eben nicht garantiert sind.
-
hustbaer schrieb:
Ich kenne keinen der "tatsache. ist ja ein ding." im Ernst sagt (und erst recht nicht schreibt)
Doch, mich.
-
Dann hab ich es falsch verstanden, bitte um Verzeihung!
-
Aber warum ist das schneller?
Warum funktioniert es nicht mit einem Cache an den x-Prozessoren angeschlossen sind?
Klar, weil man die dann gegeneinander Synchronisieren muss, aber das kann doch nicht unmöglich sein, dass das nur dann passiert, wenn die auf die gleichen Speicherbereiche zugreifen."Tatsache. Ist ja ein Ding." sollte wirklich nicht schnippisch oder so gemeint sein. Ich wollte einfach nur ausdrücken, dass ich gegoogelt habe, das gefunden habe und es mich überrascht hat.
jenz
-
Weil der Cache der Grund ist, warum Prozessoren überhaupt noch so schnell sein können. Da RAM-Zugriffe so langsam sind, brauchen die Prozessoren einen kleinen Speicherbereich in dem sie Werte zwischenspeichern können, die bald wieder gebraucht werden.
Der Fall, dass zwei Prozessoren auf den selben Daten arbeiten ist nicht der Normalfall. Eher ist das so, dass einfach unterschiedliche Software auf unterschiedlichen Kernen mit unterschiedlichen Daten werkelt.
Wenn die sich jetzt aber den Cache teilen, überschreiben sie sich ständig gegenseitig den Cache-Inhalt (der L1-Cache ist ziemlich klein, also werden bereits durch eine Anwendung alleine permanent Daten rein geladen oder raus geworfen). Womit der Nutzen eines Cache ziemlich exakt 0 ist.
-
EDIT: Blödsinn.
-
man müsste den cache natürlich ein bisschen anpassen.
zum beispiela) cachegröße = x-prozessoren*normale cachegröße
b) jeder prozessor darf nur maximal normale cachegröße (+vielleicht etwas mehr) an daten im cache habenman hätte also einen gemeinsamen größeren cache der von x-prozessoren gleichzeitig genutzt wird der nie komplett von einem prozessor benutzt wird.
was spricht dagegen?
-
Was spricht denn dafür, wenn für einen Kern kein Mehrwert entsteht? Du hast dann lediglich längere Leitungen vom Kern zum Cache, aber keinen Vorteil.
Wenn jeder Kern etwas mehr im gemeinsamen Cache benutzen darf, musst du wieder eine Verwaltung einführen, die sich merkt, welcher Bereich von welchem Kern benutzt wird. Dafür geht dann wieder Speicher und vor allem Zeit drauf. Das ist natürlich kein Ding der Unmöglichkeit (der L3-Cache ist ja ein gemeinsam verwendeter Cache), aber es ist schneller, wenn jeder Kern erstmal seinen eigenen Cache nur für sich alleine hat.
-
der mehrwert wäre, dass man den cache nie an die anderen prozessoren mitteilen muss. diese zeit würde man also sparen.
okay, wenn man mehr als nur seinen xten teil nutzen können soll, dann wird die verwaltung aufwendiger. dann sollte man den cache doch besser in gleiche teile aufteilen auf denen immer nur ein prozessor die hoheit hat.
jenz
-
jenz schrieb:
der mehrwert wäre, dass man den cache nie an die anderen prozessoren mitteilen muss. diese zeit würde man also sparen.
Würde man nicht. Angenommen du hast eine Variable x. Kern 1 benutzt x in seinem Cacheteil C1, Kern 2 benutzt x in seinem Cacheteil C2. Wenn Kern 1 den Wert von x in C1 verändert, bekommt Kern 2 das nicht mit, weil in C2 nichts geändert wird. Du müsstest also die entsprechenden Speicherstellen in C1 und C2 miteinander verschränken, d.h. synchronisieren. Die Alternative wäre, dass es für jede gemeinsam verwendete Variable eine Lookup-Tabelle gibt, die für jeden Kern die Speicherstelle in seinem jeweiligen Cacheteil angibt. Dann müsste jeder Kern jede Speicherstelle aus der Lookup-Tabelle aktualisieren. Dabei musst du dann wieder sicherstellen, dass keine zwei Kerne das gleichzeitig machen etc.
Edit: Edit weggemacht.