Multithreading, volatile, Cache usw.
-
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.
-
ich stelle mir das so vor:
lesen/schreiben darf jeder prozessor auf den ganzen cacheein- und auslagern darf immer nur der prozessor mit "hoheit" für den cachebereich
dann braucht man nichts verschränken.
könnte sogar die cachehits verbessern
-
So, hab mich jetzt selbst mal ein bisschen informiert. Bei der Verknüpfung der Byteadressen mit ihrer Bedeutung dürfte es tatsächlich keine Probleme geben, weil sich darum die MMU kümmert. Dafür ist bei Shared Caches die Latenz viel größer. Siehe z.B. http://people.engr.ncsu.edu/efg/506/s01/lectures/notes/lec16.html oder http://realworldtech.com/page.cfm?ArticleID=RWT101405234615&p=2
-
Ah, danke.
Du meinst das hier:
Latency. Switch logic will now need to be interposed between the processor and the cache, adding latency to each reference.
Oder?Das verstehe ich so, dass immer nur ein Prozessor mit dem Cache "verbunden" ist.
Man könnte doch auch einfach x-Leitungen legen und jeder Prozessor kann einfach zugreifen.
Das würde auch gleich das "Bandwidth"-Problem lösen.Das hier
"Destructive interference—the converse of overlapping working sets"
haben wir ja schon gelöstWahrscheinlich scheitert es dann aber an den ganzen Leitungen und dem verfügbaren Platz und der nötigen Länge der Leitung, wodurch es dann wieder langsamer wird.
-
Es gibt viele Cachearten, aber der große Vorteil ist der konstante Speicherzugriff auf den Cache. Manche Caches lösen lediglich den virtuellen Adressraum zur physikalischen Adresse auf (z.B Software: Paging des Betriebsystems), andere speichern Daten (z.B Hardwarecache). Deine Idee, den Cache zu sharen bringt einfach das Problem mit sich, dass der Zugriff auf gecachte Daten synchronisiert werden muss und länger braucht. Der besteht aus sehr vielen gleichen E-Schaltkreisen die echt-parallel zum Ergebnis kommen: "Hier ist der Wert" bzw. "Keiner hat den Wert". worst-case, eine echte RAM Anfrage, die je nach RAM-Timings (wobei man hier nicht 1:1 die Timings auswerten kann) 10 oder mehr Zyklen braucht. Und selbst da darf man nicht zu naiv werden. Auf primitiver Assemblerebene ist die Nebenläufigkeit von so vielen Anweisungen so hoch, dass eine RAM Anfrage geschickt wird und dann wird i=5*3, m=999/34 oder sonst was ausgeführt und irgendwann kommt der erfolgreiche Fetch. Schau dir mal eine Pipeline an. Was der L1,2,3 Cache macht (inklusiv vs. exklusiv). Was direkte Abbildung, assoziativ und mengenassoziativ bedeutet. Caches halten ihre Daten nach Hit-Rates etc. es ist verdammt gut optimiert!
Ich denke dass die Halbleiterindustrie sich täglich etliche Male den Kopf zerbrochen und nachgemessen hat und so ist es am schnellsten. Und wenn du meist, dass sich da noch was rausholen lässt, dann schau die Mal virtuelle Speicheradressen und Paging an. Das ist alles auf OS-Ebene fern von Hardware und es wird geschaut, wie optimiert wird.
-
PhilippHToner schrieb:
Deine Idee, den Cache zu sharen bringt einfach das Problem mit sich, dass der Zugriff auf gecachte Daten synchronisiert werden muss und länger braucht.
was genau muss sychronisiert werden?
bzw. wieso muss das vom cache synchronisiert werden?wenn auf gleiche daten zugegriffen werden soll, dann muss das doch von der software synchronisiert werden.
-
jenz schrieb:
Man könnte doch auch einfach x-Leitungen legen und jeder Prozessor kann einfach zugreifen.
Man betone "einfach". Also sei ma ned böse, aber du hast ja mal gar keine Vorstellung von dem Inhalt einer CPU, geschweige denn, wass das Ding in kürzester Zeit verrichtet! Lass das Thema lieber bevor, du dich hier mehr blamierst!
-
naja, es geht nur um speicher bzw. cache zugriff.
klar kann x nicht beliebig groß werden.
aber x = 4 sollte das doch machbar sein.und ich glaube, ich habe mehr ahnung als du vermutest.
vermutungen müssen wir aber nicht anstellen, ich will das doch nur mal durchdiskutieren und verstehen, wo die grenzen liegen bzw. wo die grenzen herkommen.
-
jenz schrieb:
PhilippHToner schrieb:
Deine Idee, den Cache zu sharen bringt einfach das Problem mit sich, dass der Zugriff auf gecachte Daten synchronisiert werden muss und länger braucht.
was genau muss sychronisiert werden?
bzw. wieso muss das vom cache synchronisiert werden?wenn auf gleiche daten zugegriffen werden soll, dann muss das doch von der software synchronisiert werden.
Stell Dir das so vor. Im Gegensatz zu Intel und AMD sind wird kleine Sesselfurzer, die einfach coden. Wir machen uns nicht über alles Sachen Gedanken, die Architektur spezifisch sind.
Hier ein MUsterbeispiel, dass 100000000 läuft und einmal abstürzt mit Pseudecode
RAM g = 0 // befindet sich im RAM Thread A führt Block A aus Thread B führt Block B aus Block A Warte 10 Sekunden g = 5 Blockende Block B Warte 20 Sekunden // Was für Wert ist in g? Blockende
Schau die den Code an. Ich synchronisiere hier über die Zeit, aber was ist, wenn g noch im Cache ist und das g im RAM noch wie vor 0 ist!?!?!
Deshalb Synchronisierungsverfahren, die die Cores dazu bewegt ihren Abgleich bzgl. RAM durchzuführen!
DIe besten Sync-Verfahren dich ich gesehen habe war sowas wie:if(millisecs % Threadanzahl == threadid)
// dann darf ich was machen
endif;NEVER!
-
PhilippHToner schrieb:
Im Gegensatz zu Intel und AMD sind wird kleine Sesselfurzer, die einfach coden. Wir machen uns nicht über alles Sachen Gedanken, die Architektur spezifisch sind.
Trotzdem wird man sich doch wohl mal Gedanken dazu machen dürfen, oder?
Dein anschließendes Beispiel hat nichts mit Shared Caches zu tun.