Hallo,
Was der Artikel aber sehr treffend beschreibt sind die vielen Einschränkungen die die existierenden CPUs bei LL/SC machen, damit wird dieses eigentlich gute Konzept erheblich beschnitten. Vor allem die vielen Möglichkeiten für "False Negatives" sind mMn ein echtes (Performance-)Problem.
Die Frage die ich mir stelle ist: ist dieser Transactional Memory wirklich schneller als ein Lock?
Man spart sich zumindest die zusätzlichen Lock-Variablen (so wie auch beim LL/SC). Wenn das Lock selber nichts kostet dann wohl nicht, denn zwischen Busy-Waiting und vergeblichen Versuchen ist IMHO kaum ein Unterschied (von der allgemeinen System-Last und dem Energieverbrauch mal abgesehen). Der entscheidende Punkt ist ob man beim Locking sofort merkt ob man erfolgreich war und wie das mit den Nachteilen ist (ob z.B. während so eines Code-Abschnitts geschedult werden kann). Klassisches Locking hat einige Nachteile die vor allem dadurch entstehen das der Lock belegt bleibt auch wenn der Besitzer-Thread geschedult oder gar gekillt wird (bei letzterem hat man sogar ein ernstes Problem weil dann ja eventuell die geschützte Datenstruktur in einem inkonsistenten Zustand ist kann man das Lock ja nicht so einfach wieder freigeben). Das ist ja gerade der Vorteil der CAS-Operation das es dort gar nichts persistentes gibt, wogegen es beim LL/SC-Pärchen und auch beim Transactional Memory ja doch irgendwie eine gewisse Persistenz gibt. Auch beim Transactional Memory muss diese atomare Transaktion ja irgendwo verzeichnet sein und könnte bei schlechter HW-Implementierung eventuell länger als nötig bestehen bleiben und möglicherweise andere Operationen behindern, bei der Variante mit der Cache-Line-Versionierung trifft das aber nicht zu (auf Kosten sicher erheblichen zusätzlichen HW-Aufwands).
Grüße
Erik
Transactional Memory könnte auch interessant sein ....Oh ja, das hab ich mir auch schon öfters mal überlegt. Dabei gibt es aber einige Probleme bei der praktischen Umsetzung: man muss z.B. ganz klar die Limits definieren also wie viele Speicherstellen maximal an so einer Transaktion beteiligt sein dürfen. Aus meiner Sicht wäre z.B. das Einfügen/Löschen eines Elements in/aus einer doppelt verketteten Liste so eine Operation für die man 2 Speicherstellen einbeziehen müsste (den Next-Pointer beim vorderen Element und den Prev-Pointer beim nachfolgenden Element). In dem Artikel steht drin dass das dort im Cache gemacht wird, insbesondere das mit den Versionen für die Daten klingt interessant aber auch aufwendig. Zum einen wird durch die Versionierung die Indexierung des Cache komplexer (und zwar immer und nicht nur für atomare Transaktionen, da ja komplexere HW-Logik erforderlich ist) und die Commit-Operationen müssten den Cache serialisieren (während einer Commit-Operation darf gar keine andere Operation gerade in diesem Cache stattfinden bzw. es muss sichergestellt werden das diese anderen Operationen nicht mit dem Commit kollidieren) was auch mit einigem Schaltungsaufwand verbunden ist und für die anderen CPUs Wartezeiten erzeugt. Da ich ja vor habe meiner CPU die Möglichkeit zu geben User-Mode-Code für kurze Code-Abschnitte ununterbrechbar zu machen hatte ich mir überlegt für so ein LL/SC-Pärchen die betreffende Cache-Line einfach so lange nicht raus zu rücken wenn eine andere CPU danach fragt, das würde die ganze Verwaltung dieses HW-Locks deutlich vereinfachen und auch das TimeOut wäre automatisch mit eingebaut da diese Ununterbrechbarkeit ja von begrenzter Dauer ist. Wenn es nun noch möglich wäre 2 solcher LL/SC-Pärchen zu verschachteln und die beiden SC-Zugriffe zu kombinieren (so das entweder beide klappen oder keiner klappt) dann hätte man eine simple Form des Transactional Memory und könnte damit zumindest das Einfügen/Löschen eines Elements in/aus einer doppelt verketteten Liste lockfrei realisieren. Wenn man die Cache-Line während dessen tatsächlich nicht raus gibt ist das erfolgreiche Abschließen des Commits (also der 2 SC-Befehle) eigentlich fast garantiert (solange man auch erfolgreich durch die 2 LL-Befehle gekommen ist, gerade deswegen betrachte ich es auch als so wichtig das der LL-Befehl ebenfalls melden kann ob er erfolgreich war und weil man damit die Ressourcen-Schonung des Busy-Waitings mit der optimistischen Vorgehensweise der lockfrei-Algorithmen verbindet) und wenn während dessen eine andere CPU mit einem LL-Befehl kommt dann wartet diese einfach ein paar Takte länger bis sie die betreffende Cache-Line zur exklusiven Nutzung bekommt (die Wahrscheinlichkeit für einen fehlgeschlagenen LL-Befehl ist damit auch sehr gering und es geht alles mit maximaler Geschwindigkeit vorwärts da ja jede CPU genau so lange wartet bis sie dran ist).
Was der Artikel aber sehr treffend beschreibt sind die vielen Einschränkungen die die existierenden CPUs bei LL/SC machen, damit wird dieses eigentlich gute Konzept erheblich beschnitten. Vor allem die vielen Möglichkeiten für "False Negatives" sind mMn ein echtes (Performance-)Problem.
Die Frage die ich mir stelle ist: ist dieser Transactional Memory wirklich schneller als ein Lock?
Man spart sich zumindest die zusätzlichen Lock-Variablen (so wie auch beim LL/SC). Wenn das Lock selber nichts kostet dann wohl nicht, denn zwischen Busy-Waiting und vergeblichen Versuchen ist IMHO kaum ein Unterschied (von der allgemeinen System-Last und dem Energieverbrauch mal abgesehen). Der entscheidende Punkt ist ob man beim Locking sofort merkt ob man erfolgreich war und wie das mit den Nachteilen ist (ob z.B. während so eines Code-Abschnitts geschedult werden kann). Klassisches Locking hat einige Nachteile die vor allem dadurch entstehen das der Lock belegt bleibt auch wenn der Besitzer-Thread geschedult oder gar gekillt wird (bei letzterem hat man sogar ein ernstes Problem weil dann ja eventuell die geschützte Datenstruktur in einem inkonsistenten Zustand ist kann man das Lock ja nicht so einfach wieder freigeben). Das ist ja gerade der Vorteil der CAS-Operation das es dort gar nichts persistentes gibt, wogegen es beim LL/SC-Pärchen und auch beim Transactional Memory ja doch irgendwie eine gewisse Persistenz gibt. Auch beim Transactional Memory muss diese atomare Transaktion ja irgendwo verzeichnet sein und könnte bei schlechter HW-Implementierung eventuell länger als nötig bestehen bleiben und möglicherweise andere Operationen behindern, bei der Variante mit der Cache-Line-Versionierung trifft das aber nicht zu (auf Kosten sicher erheblichen zusätzlichen HW-Aufwands).
Grüße
Erik

Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken

Gespeichert
eine 