Multithreading, volatile, Cache usw.
-
hustbaer schrieb:
BTW: die Konsistenz zwischen den Caches ist auch kein eigentliches Problem, da gibt es schöne Lösungen die gut funktionieren und vor allem auch ohne extrem viel Performance zu kosten. z.B. MESI
Ja, ich glaube ja auch, dass es so, wie es ist eine sehr gute Lösung ist.
Also das getrennte L1/L2 und gemeinsame L3 Caches (Intel) gut funktionieren.Aber ich frage mich, ob es prinzipiell besser ist L1(/L2) zu trennen.
Jetzt lese ich noch mal einen anderen Post.
Danke für deine Gedanken.
-
Ich verstehe nicht warum du immer auf "prinzipiell" rumreitest.
Es ist ein praktisches Problem - und mir zumindest reicht es vollkommen aus, wenn man etwas praktisch nicht lösen kann. Ich meine es bringt mir auch nix wenn ich weiss dass man Schach prinzipiell komplett durchrechnen kann. Mit der Info könnte ich genau nix anfangen, weil es praktisch eben trotzdem unmöglich ist.
-
hustbaer schrieb:
Jeder "gute" Cache ist "multi-way associative", d.h. jede RAM Adresse kann an verschiedenen Stellen im Cache liegen. D.h. es gibt hier gewisse Registerbänke die "Verwaltungsdaten" enthalten. Es wird z.B. auch vermerkt wann eine Cache-Line das letzte mal verwendet wurde, damit entschieden werden kann welche Lines rausfliegen wenn neue Daten dazukommen.
Um also einen neuen Wert in den Cache zu tun muss man erstmal folgendes machen:
* In allen Cache-Lines die in Frage kommen nachgucken wie alt sie sind
* Die älteste ermitteln
* Diese Cache-Line ggf. in den Speicher (oder darunterliegenden Cache) zurückschreiben
* Die neuen Daten in die Cache-Line stecken
* Den "letzer Zugriff" Wert aktualisierenWie soll das funktionieren wenn das 2 Cores gleichzeitig machen sollen?
Deswegen stelle ich mir das so vor, dass von Anfang an klar ist, dass Prozessor 1 die Cachelines 1-9 und Prozessor 2 die Lines 10-19 usw. verwaltet.
Das Lesen aus "fremden" cachelines würde ich "optimitisch" machen, also einfach draufloslesen. wenn die cacheline dann rausgeschmissen wird, dann wird der lesevorgang ab dann ungültig und muss wiederholt werden.
-
jenz schrieb:
hier drin scheint es genau darum zu gehen:
http://www.springerlink.com/content/mx6683v800477x13/
collective cache
such ich mal nach
Kauf dir des Buch. Deine Lösung konvergiert einfach zur dazu, dass es langsamere aber mehrere Prozessoren gibt, die irgendwie an der Northbridge ein shared memory haben, welches schneller ist als RAM und trotzdem werden sie nach wie vor einen NOT-Shared L1 cache machen, weil es einfach Sachen gibt, die keine anderen Prozessor interessieren, also wieso teuer im shared memory abspeichern! Du kannst gerne noch 20 Hierarchien um die bestehende bauen, aber die schnellsten Einheiten werden niemals Shared sein!
Ich habe mir auch schon Hierarchien durchgelesen, die baumstrukturartig immer N Prozessoren mit einem SharedCache versehen. Wenn Prozessor dann was von woanders braucht, muss der richtige Weg durch den Baum-Graphen gefunden werden. Das sind alles Sachen, die vielleicht kommen, aber dann haben diese Dinger immernoch ein NOT-Shared L1 Memory oder wie es dann genannt wird!
-
jenz schrieb:
Das Lesen aus "fremden" cachelines würde ich "optimitisch" machen, also einfach draufloslesen. wenn die cacheline dann rausgeschmissen wird, dann wird der lesevorgang ab dann ungültig und muss wiederholt werden.
Und wie bekommt die lesende CPU mit wenn die schreibende CPU gerade was schreibt während die lesende liest?
Und die lesende dadurch Schrott gelesen hat?Also woher weiss die dann dass es Schrott war?
-
hustbaer schrieb:
jenz schrieb:
Das Lesen aus "fremden" cachelines würde ich "optimitisch" machen, also einfach draufloslesen. wenn die cacheline dann rausgeschmissen wird, dann wird der lesevorgang ab dann ungültig und muss wiederholt werden.
Und wie bekommt die lesende CPU mit wenn die schreibende CPU gerade was schreibt während die lesende liest?
Und die lesende dadurch Schrott gelesen hat?Also woher weiss die dann dass es Schrott war?
Weil sich die "ID" der Line geändert hat.
Dafür reicht dann auch ein Bit.
-
Naja die ID könnte aber zufällig noch gepasst haben - kann ja alles mögliche rauskommen, auch was was teilweise stimmt.
Der Leser müsste schon 2x lesen oder so, um zu checken dass da was nicht passt.OK, irgendwie liesse sich das vielleicht noch hinbiegen, aber einfach stell ich es mir nicht vor.
-
hustbaer schrieb:
Naja die ID könnte aber zufällig noch gepasst haben - kann ja alles mögliche rauskommen, auch was was teilweise stimmt.
Der Leser müsste schon 2x lesen oder so, um zu checken dass da was nicht passt.OK, irgendwie liesse sich das vielleicht noch hinbiegen, aber einfach stell ich es mir nicht vor.
Er bräuchte nur das eine Bit zweimal lesen, einmal bevor er liest und einmal wenn er fertig ist. Das ergebniss wäre dann ein Cachemiss, also auch ganz "normal".
Das Bit bräuchte auch immer nur zwischen 1 und 0 wechseln. Dabei gehe ich davon aus, dass das ersetzen einer Line wesentlich länger dauert als das Lesen eines Wertes.
Also Ablauf:
- line suchen
-> möglicher cachemiss wenn nicht gefunden
- line gültig?
-> möglicher cachemiss wenn nicht ungültig
- line bit speichern
- wert aus line auslesen
- line bit mit gespeichertem vergleichen
-> möglicher cachemiss, wenn bit wert gewechselt hat.
und das hier muss vielleicht auch noch mal gemacht werden:
- line gültig?
-> möglicher cachemiss wenn nicht ungültig
-
jenz schrieb:
Er bräuchte nur das eine Bit zweimal lesen, einmal bevor er liest und einmal wenn er fertig ist. Das ergebniss wäre dann ein Cachemiss, also auch ganz "normal".
Und was wenn während dem lesen 2 schreib-operationen waren? das bit sich also 2 mal geändert hat und beim 2. lesen wieder auf dem ursprungswert steht?
-
Shade Of Mine schrieb:
jenz schrieb:
Er bräuchte nur das eine Bit zweimal lesen, einmal bevor er liest und einmal wenn er fertig ist. Das ergebniss wäre dann ein Cachemiss, also auch ganz "normal".
Und was wenn während dem lesen 2 schreib-operationen waren? das bit sich also 2 mal geändert hat und beim 2. lesen wieder auf dem ursprungswert steht?
Ja, stimmt. Ich bin einfach mal davon ausgegangen, dass Lesen schneller ist als Schreiben.
Wenn das falsch ist, dann hilft vielleicht nur ein (2-Bit?)-Counter
-
Hier hats mal jemand simuliert.
ogun.stanford.edu/publications/ISCA96.pdf
Der gemeinsame L1 Cache ist nicht genau so implementiert, wie ich mir das vorgestellt habe, aber es ist ein gemeinsamer L1 Cache.
Scheint auch ganz gut abzuschneiden.
Aber es wird auch gesagt, dass die auch ein paar ungenauigkeiten haben.
-
Ich habe beim Ueberfliegen keine MHz-Angabe gefunden. Ich denke bei 3 Ghz sieht die Sache anders aus. Mit sequenzieller Logik kann man keinen Blumentopf gewinnen. Aber hey, schaffen wir einfach Loesungen und suchen uns dann das Problem, so prinzipiell.
-
Hat das jetzt eigentlich noch irgendwas mit C++ zu tun?
-
@camper:
Nöjenz schrieb:
Hier hats mal jemand simuliert.
Dir ist schon aufgefallen dass das Paper ca. 15 Jahre alt ist. Also aus einer Zeit stammt wo das Internet noch aus Holz war, und CPUs mit Dampf betrieben wurden.
-
Shade Of Mine schrieb:
jenz schrieb:
Er bräuchte nur das eine Bit zweimal lesen, einmal bevor er liest und einmal wenn er fertig ist. Das ergebniss wäre dann ein Cachemiss, also auch ganz "normal".
Und was wenn während dem lesen 2 schreib-operationen waren? das bit sich also 2 mal geändert hat und beim 2. lesen wieder auf dem ursprungswert steht?
oh, ich glaube, du gehst von dem schreiben eines wertes aus.
das muss natürlich ganz normal zwischen den prozessen synchronisiert werden.
-
hustbaer schrieb:
@camper:
Nöjenz schrieb:
Hier hats mal jemand simuliert.
Dir ist schon aufgefallen dass das Paper ca. 15 Jahre alt ist. Also aus einer Zeit stammt wo das Internet noch aus Holz war, und CPUs mit Dampf betrieben wurden.
oh, habe ich glatt übersehen.
naja, habe noch ein bisschen gelesen, scheint auf lauftzeiten und "verdrahtung" hinauszulaufen, warum man die L1 caches trennt.
-
jenz schrieb:
naja, habe noch ein bisschen gelesen, scheint auf lauftzeiten und "verdrahtung" hinauszulaufen, warum man die L1 caches trennt.
Ach!
-
otze schrieb:
jenz schrieb:
naja, habe noch ein bisschen gelesen, scheint auf lauftzeiten und "verdrahtung" hinauszulaufen, warum man die L1 caches trennt.
Ach!
haste vorher gewusst, was?
-
self quote 4tw:
knivil schrieb:
Klar wird der Cache immer dicker, wenn er mehr Leitungen hat, aber das ist doch kein prinzipielles Problem.
Doch!
-
Da es hier vorhin um langsame Mutex ging:
Ein Mutex ist also langsam weil die Chaches meherer CPUs synchronisiert werden müssen.Ich habe folgenden Fall: Ich habe eine Datenstruktur, die EVENTUELL mal von mehreren Threads bearbeitet wird. Zur Zeit aber nur einer. Da ich die passende Infrastruktur möchte, wurde alles mit Locks ausgestattet.
Bremsen die Locks jetzt den Thread auch so stark aus, wenn er eigentlich allein auf den Daten operiert?