Eine Frage zu den Details von Speicherfunktionen in PCs:
Die Zugriffsgeschwindigkeit bei DDR3- und DDR4-Speichern scheint sich ja in Richtung Latenz zu entwickeln, bei verbesserter Bandbreite. Ich habe mich die vergangenen Tage mit den Details zu beschäftigen gehabt und stolpere über eine Frage:
Was macht den realen Speicherzugriff langsam?
Die brutto ausrechenbaren Bandbreiten werden so gut wie nie erreicht. Im Gegenteil: Mehr als 60%-80% sind nicht zu erzielen. Bisher dachte ich, dass dieses durch u.a. den refresh verursacht wird. Ich lese aber in der WP, dass dies nur wenige Bruchteile von Prozenten zu sein scheinen, wenn die Rechnung dort stimmt:
Zu lesen ist dort, dass bei 64ms nur ein halbes Prozent aus macht, wenn die Rechnung stimmt. Das sollte man in der Praxis kaum merken.
Woher kommt der Rest? Sind das die Bank- und Seiten-Umschaltungen? Oder die ungenutzten bursts?
Davon ausgehend, daß selbst kleine Pakete für Bilder und sonstige Daten wie mp3 oder auch Messtechnikdaten im Bereich viele Kilobytes liegen, sollte der größte Teil eines solchen Auslesevorgangs mit voll gefüllten und genutzten bursts und auf derselben Seite stattfinden. Eine Bildzeile z.B. hat 2000 Punkte = 6000 Bytes, davon kann nur der letzte burst überwiegend leer sein, wenn es sinnvoll gefragt wird und abgespeichert wurde. D.h man sollte bei einem 32 Byte burst über hundert volle Paket bekommen. Macht wieder weniger als 1% Verlusts.
Es müssten also Seitenwechsel sein. Oder? - Aber warum macht das so viel aus?
Kann es sein, dass einfach das Betriebssystem zu viel "gleichzeitig" machen will und deshalb Anfragen von zuvielen Prozessen zu kleinkariert prozessiert, statt Speicherzugriffe zu bündeln?
Die brutto ausrechenbaren Bandbreiten werden so gut wie nie erreicht. Im
Gegenteil: Mehr als 60%-80% sind nicht zu erzielen. Bisher dachte ich,
dass dieses durch u.a. den refresh verursacht wird. Ich lese aber in der
WP, dass dies nur wenige Bruchteile von Prozenten zu sein scheinen, wenn
die Rechnung dort stimmt:
Mein Speicher ist sauschnell und erreicht > 90% der theoretische Bandbreite. Hast du dir mal die Mühe gemacht, ein ordentliches Benchmarkprogram laufen zu lassen?
Hast du dir mal die Mühe gemacht, ein ordentliches
Benchmarkprogram laufen zu lassen?
Und damit sind wir beim Punkt: Um den Durchsatz von RAMs voll auszukosten, benötigt man Software, die darauf optimiert ist. Benchmarks sind es. Normale Anwendungen nicht.
Kann es sein, dass einfach das Betriebssystem zu viel "gleichzeitig"
machen will und deshalb Anfragen von zuvielen Prozessen zu kleinkariert
prozessiert, statt Speicherzugriffe zu bündeln?
Eher nicht, die Kontextwechsel von PC-Betriebssystemen sind viele Größenordnungen langsamer als die einzelnen Speicherzugriffe. Auch dank Mehrkern-Prozessoren werden leistungshungrige Anwendungen (z.B. Spiele) sowieso eher selten unterbrochen.
Das Hauptproblem ist einfach die Latenz, bis die Bits rauskommen.
Die brutto ausrechenbaren Bandbreiten werden so gut wie nie erreicht. Im
Gegenteil: Mehr als 60%-80% sind nicht zu erzielen
Die große Kunst ist es, die Speicherzugriffe so zu organisieren, das die Bandbreite auch ausgenutzt werden kann. In einer heutigen CPU gibt es viele verschiedene Einheiten die dann und wann was vom Speicher wollen. Der eine Hersteller kann das besser, der andere schlechter. Die maximal mögliche Bandbreite gilt außerdem nur für sequentiellen Zugriff mit möglichst großen Blöcken - ein Zugriffsmuster was in der Realität nicht unbedingt an der Tagesordnung ist.
Die maximal
mögliche Bandbreite gilt außerdem nur für sequentiellen Zugriff mit
möglichst großen Blöcken
Eine Maschine mit vielen parallel laufenden und voneinander unabhängigen Prozessen/Threads kann dabei auch helfen. Wenn dabei genug Requests zusammen kommen, um die Lücken zu stopfen, die andere Threads bei den Zugriffen lassen. An die volle Bandbreite kommt man da nicht heran, aber es wird besser als beim Anwender-PC.
Eine Maschine mit vielen parallel laufenden und voneinander unabhängigen
Prozessen/Threads kann dabei auch helfen.
Wie? Dort wird doch nur die Bandbreite aus Sicht der nutzenden Prozesse ausgenutzt, d.h. das, was der eine nicht verbraucht, kann der andere haben. Mir geht es aber darum, für einen einzigen Schreibe und Lese-Prozess die Bandbreiten bereitstellen zu können.
Hat jemand eine Quelle, anhand derer man einen solchen Speicherzugriff
nachvollziehen kann?
Nimm dir einfach ein Datenblatt eines beliebigen RAMs Chip, da steht alles drin. Typischerweise werden die Daten auch in "Bursts" gelesen, d.h. es wird nie eine Speicherzelle, sondern meist 4-8 Zugriffe der selben Art direkt hintereinander, hängt vom RAM Typ ab.
Andere Idee: Kann eine unglückliche Cache-Nutzung die Bandbreite
verschlechtern?
Ich denke die Speicherzugriffsmuster in der Anwendung sind da kritischer. Wenn du z.B. viele kleine Häppchen an verschiedenen, weit auseinanderliegenden Adressen im Wechsel liest und schreibst, dann ist das ganz schlecht. Weil er ständig die Pages wechseln muss
Mir geht es aber darum, für einen einzigen Schreibe und
Lese-Prozess die Bandbreiten bereitstellen zu können.
Dann gilt es nicht nur, sich mit dem Speicher zu beschäftigen, sondern auch mit den konkreten Prozessor. Wie man die Befehle passend arrangiert, und welche man dafür verwendet. Wie der Prefetch des Prozessors arbeitet, wie man ggf am Cache vorbei operiert, wenn der aufgrund zu grosser Datenmengen sowieso nur im Weg steht. Und was man den Performance Countern des Prozessors entnehmen kann.
Hat jemand eine Quelle, anhand derer man einen solchen Speicherzugriff
nachvollziehen kann?
Könnte man das mit RAS/CAS timing nicht beispielhaft berechnen, wie und
in welchen Fällem welche Verluste auftreten?
Andere Idee: Kann eine unglückliche Cache-Nutzung die Bandbreite
verschlechtern?
Die Speicherbandbreite hängt vom Speichertakt ab, von der Breite des Speicherinterfaces und von der Anzahl der Speicherkanäle.
Auf dem Laptop hier etwa 2400 MHz * 8 Bytes * 2 = 38400 MB/sec.
Windows "winsat mem" als Admin gestartet liefert 35.2 MB/Sec, also 92% der theoretischen Bandbreite. Der Cache ist ist typischwerweise 8-way associative, du kannst also 8 Blöcke mit kollidierenden Addressen im Cache halten. Der L1 Cache ist dazu separat für Daten und Instruktionen.
Wie man jetzt genau die Latenz ausrechnet, überlasse ich dem Dipl.-Ing. in deinem Namen.
Und damit sind wir beim Punkt: Um den Durchsatz von RAMs voll
auszukosten, benötigt man Software, die darauf optimiert ist. Benchmarks
sind es. Normale Anwendungen nicht.
Eigentlich macht das die Hardware selbständig. Jedes Program, dass ein paar MB am Stück liest, hat 90% der maximalen Performance.
Ich würde eher sagen, dass es verdammt schwer ist einen heutigen Cache Controller zu überlisten. Selbst wenn du die Bytes in kleinen Häpchen liest, ist die Performance ziemlich gut, solange die Daten nicht zufällig im Hauptspeicher verteilt sind. Normalerweise sind die Daten nach dem ersten Lesen oder beim Schreiben im L1/L2/L3 Cache, die DDRAM Geschwindigkeit und Latenz spielt daher nur bei sehr grossen Daten eine Rolle. Daher ist die Geschwindigkeit von DDRAM für die meisten Anwendungen unwichtig.
Typischerweise werden die Daten auch in "Bursts" gelesen,
d.h. es wird nie eine Speicherzelle, sondern meist 4-8 Zugriffe der
selben Art direkt hintereinander
Dazu kommt noch, dass nicht nur die Nutzdaten im RAM liegen, sondern auch noch das Anwendungsprogramm und das ganze BS.
Wenn man sich auf einem aktuellen Windows so umschaut, sieht man das da in der Regel über 1000 und mehr Threads aktiv sind (ganz unabhängig von der eigentlichen Anwendung). Jeder diese Threads will gelegentlich mal Prozessorzeit zugeteilt bekommen. Das heißt Kontextwechsel und vorallem dessen Programmcode muss Befehl für Befehl aus dem RAM gelesen werden. Und mehrere Kerne, die nur über ein gemeinsames Speicherinterface angebunden sind, machen das Aufteilen der Speicherzugriffe auch nicht gerade besser.
Dazwischen kommen dann auch noch Zugriffe wie auf die Festlatte oder die Netzwerkkarte, die ja auch ihre Datenblöcke im RAM zwischenlagern und dazu
ggf. noch einen weiteren Software-RAM-Cache dazwischen haben. USB und so bekommen andauernd neue Daten die vom BS auch erstmal im RAM geparkt werden bis irgendeine Anwendung die haben will usw.
Von der Grafikkarte, die ja vom BS auch immer wieder mal mit neuen Informationen (z.b. Mauszeiger ein Pixel nach rechts verschieben) gefüttert werden will, ganz zu schweigen.
Ein "passender" Cache-Mistake und alle Kerne fangen an ihr Cache erstmal wieder aus dem RAM zu aktualisieren:-)
Nochdazu, bei einer realen Anwendung ist es ja nicht damit getan, einfach nur Daten aus dem RAM zu lesen. Man braucht ja auch CPU-Befehle die die Daten lesen und man braucht auch noch Befehle, die die Daten verarbeiten und ggf. auch noch welche die die verarbeiten Daten wieder irgendwohin schaffen.
Da kommt man dann zu irgendwelchen Benchmarks. Denn kann man einigermaßen so optimieren, dass dieser möglichst komplett im Cache abläuft und die gelesen Daten aus dem RAM quasi ohne Beachtung nach DevNull entsorgt werden. Sowas dann noch in einer Version die ohne größeres BS auskommt, wie z.B. DOS, wo keine andere Thread dazwischenfunken kann und große Teile der Hardware möglichst nicht genutzt werden, dann kommt man den theo. max vielleicht nahe.
Sowas dann noch in einer Version die ohne
größeres BS auskommt, wie z.B. DOS, wo keine andere Thread
dazwischenfunken kann und große Teile der Hardware möglichst nicht
genutzt werden, dann kommt man den theo. max vielleicht nahe.
Das stimmt schon, was du schreibst. Aber wenn du mal Zahlen einsetzt, dann siehst du schnell, dass das alles nicht so schlimm ist. Es gibt nur wenige Programme, die die Geschwindigkeit des RAM ausreizten, da brauchst du grosse Datenbanken oder Film und Video Bearbeitung. Das typische Program liest und schreibt fast immer aus dem Cache. Um an die Grenzen des RAM zu kommen, musst du mindestens 30 MByte in einem Stück lesen oder schreiben. Alles drunter läuft aus dem Cache. Wenn du es nicht glaubst, schreibe ein simples Speicherkopierprogram. Du wirst sehen, dass der Speicher nicht langsamer als das RAM ist, sondern im Gegenteil viel schneller ist!
Auf meiner Windows Kiste laufen gerade mal 25 Prozesse, die mehr RAM haben als in den Cache passt, und von denen braucht kein einziger mehr als 1% CPU.
Apropos Suche nach den letzten Prozenten: Wessen aktives Grafiksystem Teil des Prozessorkomplexes ist, der sollte den Bandbreitenbedarf seiner Bildschirme mitrechnen. Deren Refresh läuft dann aus dem normalen RAM.
Apropos Suche nach den letzten Prozenten: Wessen aktives Grafiksystem
Teil des Prozessorkomplexes ist, der sollte den Bandbreitenbedarf seiner
Bildschirme mitrechnen. Deren Refresh läuft dann aus dem normalen RAM.
Ja, das ist auch ein wichtiger Aspekt. Ich habe hier im Wohnzimmer einen HTPC stehen. Früher war da mal ein Celeron 847 drinnen. Dieser hat ebenfalls eine integrierte GPU. Dekodieren von HD Streams über Satellit (ca 2,4MB/s) hat mit dem nur bei Dual-Channel RAM flüssig funktioniert. Wenn man nur einen RAM-Riegel bestückt hat, dann war die Bandbreite zu klein um die Hardwaredecoder, CPU und GPU parallel zu bedienen.
Mein Speicher ist sauschnell und erreicht > 90% der theoretische
Bandbreite.
Ich habe hier auf zwei Rechnern mal ein hand-gedengeltes 64bit Testprogramm in Assembler geschrieben.
Bei 1GiB RAM über Quadword Zugriffe beim Lesen erreiche ich ca. 11.57GB/s bei theoretisch möglichen 12.8GB/s. Das sind ebenfalls 90.4%.
(Device-1: ChannelA-DIMM0 type: DDR3 size: 4 GiB speed: 1600 MT/s)
"simples Speicherkopierprogramm", der Witz ist gut:-) Schaue dir mal alle die verschiedenen Funktionen in C/C++ an was da für eine Aufwand getrieben wird um eine paar Daten von A nach B zu kopieren. Da werden z.B. die SSE oder AVX Einheiten benutz um die Daten "zwischenzulagern" damit der RAM-Burst möglichst vollständig genutzt werden kann usw. Das ist erstmal nur die Daten von einem Speicherbereich in einen anderen Kopiert. Hier sind die Daten noch lange nicht irgendwie ver-/bearbeitet...
Viel interessanter als die Prozesse sind die Threads (kann man im Taskmanager im Tab Details einblenden). Die entscheiden darüber wieviele Aufgaben der Scheduler zu verteilen hat.
Cache-Handhabung nicht vergessen. Vielleicht will man deren Inhalte
nicht durch grössere Transfers plattwalzen, sondern darin Wichtigeres
aufbewahren.
Kommt drauf an was man erreichen möchte.
Um die Geschwindigkeit zu testen ist jedes Mittel recht (T0).
Um lieb zu anderen zu sein wird es wohl eher auf (NTA) heraus laufen.
Ob da überhaupt etwas passiert, und wenn ja was, ist arg abhängig vom konkreten Prozessor, und auch nicht unbedingt erschöpfend dokumentiert. Man kann sich dann auch in die Arbeitsweise der automatischen Prefetches einlesen, die möglicherweise ähnliche Strategien verfolgen.
Eine Frage zu den Details von Speicherfunktionen in PCs:
Jeder der sich ernsthaft mit DRAM-Speicher beschäftigt, beispielsweise mal das umfängliche Datenblatt durchgelesen hat, kennt die Gründe dafür und das die Frage so unzureichend formuliert ist.
DDR RAM ist auf Blockzugriffe aka Bursts optimiert, die gehen rasend schnell, was vielleicht einen dummen Jungen langsam erscheint sind Zugriffe mit bei nicht sequentiellen Addresses. Die werden aber auch durch Caches abgefangen, zeigen aber das Problem des gemultiplexten Adressbusses, also das Addressierung über zwei Zugriffe (Row- und Column-bestandteil) erfolgen muss.
Turnaround bei Umschaltung der Signalrichtung (read/write) sind auch nicht zu unterschätzen.
Auch wenn die englische WP oft besser als die deutsche ist ist wie wikipedia kein Ersatz fürs Datenblatt oder (Hochschul-) Fachliteratur.
Wenn man in Richtung PCB geht, tauchen weitere Probleme wie Laufzeitunterschiede und parasitäre Kapazitäten aus die zu einem Langsameren Taktschema zwingen.
zeigen aber das Problem des gemultiplexten
Adressbusses, also das Addressierung über zwei Zugriffe (Row- und
Column-bestandteil) erfolgen muss.
Wobei diese Trennung aber nicht nur Leitungen spart, sondern auch mit der internen Organisation der DRAMs zu tun hat. Für die Speicher-Matrizes braucht man zunächst eben nur den Teil der Adressbits zur Zeilenauswahl. Die Adressbits zu Spaltenauswahl haben etwas mehr Zeit.
Turnaround bei Umschaltung der Signalrichtung (read/write) sind auch
nicht zu unterschätzen.
Rambus hatte diesen Punkt adressiert, genutzt von den ersten Pentium 4 Prozessoren. Schneller wars jedoch nicht, und eckte zudem "politisch" an, weil sich die Firma in den Branche zum Paria machte.
Turnaround bei Umschaltung der Signalrichtung (read/write) sind auch
nicht zu unterschätzen.
Rambus hatte diesen Punkt adressiert, genutzt von den ersten Pentium 4
Prozessoren. Schneller wars jedoch nicht, und eckte zudem "politisch"
an, weil sich die Firma in den Branche zum Paria machte.
Rambus kenne ich nicht so im detail, aber IMHO waren deren designs zu beginn (1990's) schon schneller als der "Standard" synchrone DRAM. Natürlich fehlt IP-(fabless) Firmen wie RAMBus die "normative Kraft des Faktischen" mit denen die grossen RAM-Hersteller alle "Neu-Einsteiger" "platt machen".
rambus inc. hat ca. 600 Mitarbeiter, micron technologies dagegen 43000 .
mit denen die grossen RAM-Hersteller alle "Neu-Einsteiger" "platt machen".
rambus inc. hat ca. 600 Mitarbeiter, micron technologies dagegen 43000 .
Man ist nicht automatisch eine David'sche Lichtgestalt, bloss weil man klein ist. Wer sämtliche Goliaths mit Klagen überzieht, sollte keine Küsse erwarten.
https://en.wikipedia.org/wiki/Rambus#Lawsuits
Rambus hatte diesen Punkt adressiert, genutzt von den ersten Pentium 4
Prozessoren. Schneller wars jedoch nicht ...
und viel Strom verbrauchte es. Rambus-Module waren die ersten, die mit Kühlkörpern ausgestattet wurden, und das war lange vor der "Casemodder"/"Gamer"-Seuche.
"simples Speicherkopierprogramm", der Witz ist gut:-) Schaue dir mal
alle die verschiedenen Funktionen in C/C++ an was da für eine Aufwand
getrieben wird um eine paar Daten von A nach B zu kopieren. Da werden
z.B. die SSE oder AVX Einheiten benutz um die Daten "zwischenzulagern"
damit der RAM-Burst möglichst vollständig genutzt werden kann usw. Das
ist erstmal nur die Daten von einem Speicherbereich in einen anderen
Kopiert. Hier sind die Daten noch lange nicht irgendwie
ver-/bearbeitet...
memcpy - mehr brauchst du da nicht. Wie das funktioniert, musst du ja nicht wissen.
Falls es dich interssiert - folgenden 10 Befehle sind alles was du auf einer modernen
CPU brauchst.
Viel interessanter als die Prozesse sind die Threads (kann man im
Taskmanager im Tab Details einblenden). Die entscheiden darüber
wieviele Aufgaben der Scheduler zu verteilen hat.
Rambus hatte diesen Punkt adressiert, genutzt von den ersten Pentium 4
Prozessoren.
und viel Strom verbrauchte es. Rambus-Module waren die ersten, die mit
Kühlkörpern ausgestattet wurden,
Auch Geschwindigkeit hat ihren "Preis", dann muss man eben die Spannungspegel herabsetzen undparasitäre Capazitäten klein halten. Und die Integration (noch mehr schaltende Transistoren auf weniger Fläche) fordert als prinzipbedingter "Hot Spot" auch ihren Tribut.
Wer schnell und klein sein will muß eben mehr schwitzen um nicht zu verglühen ...
das Problem des gemultiplexten
Adressbusses, also das Addressierung über zwei Zugriffe (Row- und
Column-bestandteil) erfolgen muss.
Ich dacht, dass dieser Aspekt bei der Angabe der Bandbreite berücksichtigt sei, aber das scheint nicht der Fall szu sein. Oder doch?
Ich dachte eigentlich dass ausgehend von der nutzerseitigen Taktfrequenz von z.B. 266 MHz die auf der RAM-Seite vervielfachte Frequenz ausreichen sollte, um die Adress-Zugriffe durchzuführen.
Da der Anschluss für den Controller parallel zu den Daten ist, müsste man ohne Verzögerungen den Adressen-FIFO beschreiben können. Mit Command z.B. 2+2 = 4 Zugriffe für einen Burst. Die Daten könnten also seitens der RAM-Riegel ungehindert fließen.
Eine Maschine mit vielen parallel laufenden und voneinander unabhängigen
Prozessen/Threads kann dabei auch helfen.
Wie?
Wie bei HT beschrieben.
Windows 95 war auch definitiv schneller (u.a. mehrere FPS bei Quake), wenn man die Auslagerungsdatei auf feste Werte (Min/Max/Gesamtgröße) eingestellt hatte.
Einflussmöglichkeiten hat man auch, u.a. ausgewählte Rams, Ramposition auf dem Board, Pärchen, Alignments, Bioseinstellungen..bringt nicht viel, aber wenn man passende Messmethoden parat hat, könnte man Unterschiede finden.