Hallo,
Naja, nur wenn du sehr viele sehr große Segmente hast, ist das Problem der Fragmentierung nicht gegeben, denn die tritt hauptsächlich bei sehr kleinen (bzw. von vorne verkürzten) Segmenten auf. Das sind in der Regel nur ein paar MB oder sogar weniger.
Wieso sollte die Fragmentierung bevorzugt mit kleinen Segmenten auftreten? Gerade für kleine Segmente wird sich doch noch eher eine passende Lücke finden lassen als für große Segmente. Ein Segment das nur eine Page (kleinste Page-Größe) belegt kann gar nicht fragmentieren.
Wenn du natürlich möglichst fleißig Segmente zusammenfassen möchtest, damit die Segmente möglichst groß werden und du innerhalb der Segmente den Verwaltungsaufwand hast, dann kommt zu der externen Fragmentierung (Segmente im physischen Adressraum) auch noch interne Fragmentierung (malloc/realloc in den Segmenten) dazu. Stell ich mir unangenehm vor.
Ja, das möchte ich. Die interne Fragmentierung werde ich aber mit meinen unabhängigen dynamischen Segmenten deutlich besser in den Griff bekommen als das ein Flat-Memory-Programm je könnte.
gewisse Segmente braucht man nicht verschieben, wenn man sie im Voraus günstig platziert (z.B. Treiber).
Die Segmente für .code , .const und .data sind in ihrer Größe fest, die werden von hinten anfangend in den physischen Speicher gepackt. Die Heap-Segmente und Stack-Segmente sind flexibel und kommen von vorne anfangend in den physischen Speicher. Der Micro-Kernel in meinem OS weiß nicht was ein Treiber ist, der wird alle Programme gleich gut behandeln. Es wird aber eine Möglichkeit geben Segmente zu locken damit sie garantiert nicht verschoben werden (Treiber werden das nutzen), so ein Segment wird dann auch sofort nach vorne verlegt (der Treiber blockiert also während seiner Initialisierung ein bisschen wegen dem sofortigem verschieben oder das Segment wird gleich als gelockt erstellt), damit ist das Segment aber auch nicht mehr in seiner Größe änderbar.
Ich befürchte das ich da selbst mit möglichst intelligenter Segment-Allozierung (z.B. Best-Fit oder hinter jedem Segment was frei lassen) nicht lange ohne Defragmentieren auskomme.
Ich vermute mal schon, allerdings immer unter der Annahme von genügend physischem RAM.
Das hängt sehr davon ab wie neue Programme gestartet und beendet werden oder die Programme ihre (Heap-/Stack-)Segmente vergrößern/schrumpfen. Solange die RAM-Auslastung unter 50% bleibt sollte Defragmentieren kaum nötig sein, wird aber trotzdem mal auftreten (vor allem beim wachsen von Segmenten, da kann immer mal was anderes im Weg sein).
Auf einem normalen PC hast du in der Regel genug Idle-Zeit für solche Spielereien,
Du kennst Seti@Home oder seine Nachfolger? Von genügend Idle-Zeiten auszugehen ist meiner Meinung nach so eine Annahme die einem früher oder später richtig Ärger macht. Solche Annahmen will ich nicht treffen und auch nicht ins Design meiner Plattform einfließen lassen!
ansonsten kannst du die natürlich jederzeit auch garantieren.
Wie? Mal abgesehen davon das sowas IMHO Quatsch ist.
(Wobei garantierter Leerlauf eher nach Überhitzungsschutz klingt...)
lol
In dem Augenblick, wo Pages ausgelagert werden müssen, die noch gebraucht werden, ist ohnehin alles verloren.
Das soll ja die Page-Ersetzungs-Strategie möglichst verhindern. Die ist natürlich auch nicht perfekt und dann gibt es ein paar kurze Wartezeiten (wobei wenn die Page-Not-Present-Exception noch während des Schreibens auf die Festplatte kommt könnte der Exception-Handler die Page einfach wieder als gültig markieren und den Schreibvorgang als ungültig), aber im Durchschnitt wird die schon gut funktionieren. Wenn es gar nicht mehr anders geht fliegen IMHO die Programme mit der niedrigsten Priorität als erstes raus (die habens dann natürlich extrem schwer).
Besser als uClinux geht es fast nicht. Trotz der ganzen Probleme, die mit der Speicherfragmentierung einhergehen, läuft das System trotzdem.
Klar, in Anbetracht der Möglichkeiten die uCLinux hat ist das Ergebnis natürlich hervorragend.
aber "out of memory" bei zerstückeltem RAM gibt es selten unter 75% RAM-Auslastung. Und solche Situationen merkt man auch schon früher als Fall für den Garbage Collector.
Bei mir wird dann das Defragmentieren anspringen wenn sich für ein neues Segment nicht mehr physischer Speicher am Stück findet oder wenn ein Segment nicht einfach wachsen konnte und deshalb physisch zerteilt werden musste. Andere Gründe für das Defragmentieren fallen mir nicht ein. Einen "Garbage Collector" wird es bei mir nicht geben, kann ich mir momentan auch nicht vorstellen was der machen sollte. Das einzigste was mir einfällt sind Programme die ihren Speicher freiwillig, auf
Bitte vom OS-Kernel, wieder hergeben. Ein File-System-Cache wäre da ein gutes Beispiel, normale User-Programme trifft das eher nicht.
denn während der Kernel sein Speichermanagement mit der Festplatte abquatschen muss, geht nicht wirklich viel.
Das "abquatschen" (Verwaltungsstrukturen im Speicher ändern) dürfte bei der Performance heutiger PC-CPUs vernachlässigbar sein und der eigentliche Datentransfer wird vom Festplatten-Host-Controller selbstständig erledigt, da kann die CPU sich längst wieder um die Programme kümmern.
Besonders, wenn die Page, in der der Taskzustand steht, fehlt
Ein OS das seine eigenen Verwaltungsstrukturen auslagert hat es auch nicht besser verdient.
Ich halte das Speichermanagement für zu kritisch, als dass man nebenher die unbelasteten Anwendungen weiterlaufen lassen könnte.
Wieso? Wenn man alles ordentlich mit spinlocks o.ä. absichert sehe ich da keine Probleme. Ein passendes Konzept zu entwerfen ist sicher nicht trivial (das werde ich bestimmt früher spüren als mir lieb ist) aber nicht unmöglich. Im Linux-Kernel versucht man doch auch diesen "Big-Kernel-Lock" zu beseitigen damit der Kernel auch unter Last noch die Wünsche der Programme befriedigen kann, gerade auf einem massiven SMP-System ist das nötig.
das Problem sehe ich heutzutage aber eher darin, dass irgendein Programm amok läuft, schnell viel RAM füllt, das System in die Ecke drängt bis es dann vom Kernel OOM-gekillt wird.
Solche Programme sind natürlich ein Ärgernis. Trotzdem soll das OS auch damit einigermaßen geschickt umgehen können. Hier wären vielleicht Memory-Quotas eine Lösung. Sowas wurde, hier im Forum, schon mal diskutiert
http://lowlevel.brainsware.org/forum/index.php?topic=2256. Wenn mein OS mit Amok laufenden Programmen einigermaßen (also besser als Windows) umgehen kann dann bin ich zufrieden.
Swap als Arbeitsgrundlage braucht man mMn nicht mehr. Dazu ist RAM zu billig geworden.
ACK
Aber ganz auf Swapping verzichten kann/darf man trotzdem nicht (außer im Embedded-Bereich wo man vorher weiß welche Programme laufen werden). Swapping muss in meinem Konzept ordentlich vorgesehen sein, auch wenn ich das sicher nicht gleich beim ersten Anlauf umsetzen werde.
ob du nun das Office-Paket komplett oder zu einem Großteil ausgelagert hast, spielt da eine untergeordnete Rolle.
Das sehe ich anders. Viele Programme benutzen, über einen kurzen bis mittleren Zeitraum betrachtet, nur einen kleinen Teil des allozierten Speichers. Von einem Programm zwangsläufig alles auslagern zu müssen, anstatt nur den tatsächlich unbenutzten Teil rauszuwerfen, erscheint mir wahrlich ungeschickt.
Muss das Programm denn nur aus drei Segmenten bestehen?
Nein, die Programme werden schon ein paar Segmente mehr benötigen. Aber da die Größe der Segmente wohl in Pages (Größe der kleinsten unterstützen Page, in der 64 Bit-Variante also mindestens 64 kBytes) gemessen wird, entsteht eine Menge Verschnitt wenn man alles auf zu viele kleine Segmente verteilt. Außerdem kann die
LDT maximal 32767 Segmente aufnehmen, damit will ich schon etwas sparsam umgehen.
ein eigenes Segment vorzusehen (welches dann, da es eh zu klein ist, nicht ausgelagert würde)?
Wieso sollten kleine Segmente nicht ausgelagert werden?
Der Tastendruck gehört entweder woanders verarbeitet
Und Wo? Wenn nicht im Office-Paket?
oder aber das Office-Paket nicht ausgelagert
Genau das ist der Punkt wo ich sage das Paging die einzigste Möglichkeit ist um Knappheit für alle Programme
gleich fair abzufangen. Man kann doch schließlich nicht große Programme komplett im RAM lassen nur weil ein kleiner Teil davon benötigt wird. Ich denke jedes Programm muss etwas geben damit auch bei (leichter) Knappheit alle Programme noch einigermaßen arbeiten können.
Außerdem gehst du davon aus, dass die Programme von der Segmentierung nichts wissen (oder mitkriegen können), und somit dein System nicht entlasten können. Das sehe ich wie, wenn sich zwei Deutsche auf Englisch unterhalten - es funktioniert, ist aber schon im Ansatz falsch. Wenn du den Programmen keine segmentfreundliche Nutzung zugestehst, dann kann das nicht performant werden, einfach weil du auf der falschen Architektur arbeitest.
Ja, Du hast (in gewissen Grenzen) recht. Solange Segmentierung allgemein belächelt wird hab ich aber keine andere Wahl. Wirklich
alles selber programmieren will ich nicht, ich will auch mal ein nützliches Tool portieren können. Natürlich muss die libc genau wissen wie die Segmente zu nutzen sind, auch all die anderen Librarys welche die Dienste des OS, oder der Personality, dem eigentlichen User-Space-Programm zugänglich machen sollten wissen das sie es mit Segmentierung zu tun haben. Wenn ich mir normale C-Programme ansehe dann gehen die erstmal von gar keiner Architektur aus, ich glaube auch nicht das in den C/C++-Specs dazu was drin steht. Es ist Aufgabe des Compilers die tatsächliche Ziel-Architektur angemessen (also möglichst optimal) zu bedienen.
Wie sollten den normale User-Programme mithilfe der Segmentierung mein System entlasten?
Heutzutage ist es ja (für größere Projekte) auch üblich, dass man möglichst nicht regelmäßig den Cache kaputtmacht. Solche Rücksichtnahme auf die reale Architektur muss vorhanden sein...
Da gebe ich Dir natürlich recht. Rücksicht auf Caches und dergleichen nehmen die Programmierer aber nicht für das Betriebssystem oder die Plattform sondern für die Performance des Programms, also aus Eigennutz. Die Existenz und Wirkungsweise von Caches hat physische Ursachen um die auch ich nicht herum komme, so das all diese Tricks eben auch auf meiner Plattform funktionieren werden (wenn auch auf einem deutlich niedrigerem Niveau).
RAM-Knappheit ist der Grund fürs Swappen nicht fürs Defragmentieren.
Vor dem Swappen kommt zwangsweise ein Defragmentieren, um die letzten Speicherreste auszukratzen.
Wieso? Defragmentieren bringt keinen zusätzlichen freien physischen Speicher sondern verteilt diesen nur anders. Defragmentieren und Swappen sind 2 völlig verschiedene Dinge mit völlig verschiedenen Ursachen und völlig verschiedenen Konzepten, die nur beide (zufällig) das selbe Paging benutzen um ihre jeweilige Aufgabe zu erfüllen.
Und bei genügend RAM (oder nicht genügend RAM-Auslastung) gibt es keinen Grund zu defragmentieren.
Jedenfalls nur sehr selten.
Womit du innerhalb der Segmente den Aufwand hast.
So wie in einem Flat-Memory-Programm auch, nur das ich mit den unabhängigen Segmenten ein paar Freiheitsgrade mehr hab um die interne Fragmentierung im Zaum zu halten.
Andererseits sparst du Unmengen FAR-Pointer ein, wenn die Anzahl der Segmente der Anwendung größer wird als die Anzahl der lokalen Segmentregister...
Hä? FAR-Pointer brauch ich doch trotzdem, der Compiler weiß doch nicht vorher wo die Speicherblöcke real liegen. Ein Pointer hat genau drei verschiedene Quellen: 1. der Compiler muss eine statische Variable referenzieren (aus .const oder .data, das passiert beim Linken), oder der Compiler muss eine lokale Variable referenzieren (also die Adresse von etwas ermitteln das auf dem Stack liegt, dafür muss der Compiler etwas Code erzeugen) und 3. kommt als Rückgabewert von malloc/realloc (das ist mein Part, ob ich da unbedingt Assembler für benötige weiß ich noch nicht). Alles andere ist reine Pointer-Arithmetik.
Ich halte defragmentieren als einen Oberbegriff, nämlich wann immer die physische RAM-Aufteilung geändert werden muss. Und das betrifft grundsätzlich immer zwei Segmente - das Quell- und das Zielsegment. Wenn du die beiden in das Paging verlagerst (bzw. ein paar mehr für stark unterschiedliche Größen), kannst du die im Hintergrund deine Speichermagie betreiben.
Wieso "Quellsegment" und "Zielsegment"? Ich kopiere doch nicht den Inhalt von einem Segment in ein anderes sondern verschiebe (in Wirklichkeit natürlich kopieren) die Pages aus denen ein Segment besteht. Das Segment befindet sich für diesen Vorgang zwar im virtuellen Speicher und seine Pages sing möglicherweise total über den physischen Speicher zerstreut, aber es ist trotzdem nur ein Segment an dem gerade gearbeitet wird.
Was ich damit grundsätzlich sagen möchte, wenn du ohne Paging auskommen möchtest (es im Normalfall also eh nicht nutzen möchtest), dann brauchst du auch nicht die volle Flexibilität von Paging. Verschwendetes Silizium.
Ohne ein vollwertiges Paging bringt mir die Segmentierung aber zu viele Nachteile (zum DOS will ja niemand zurück). Natürlich kostet das Silizium aber ohne kommt kein gescheites System bei raus.
Für mich klingt es nach einer ausgewachsenen Nutzung von Paging und Segmentierung (was ich persönlich auch sehr gut finde) mit dem Designziel, die Pagingeinheit grundsätzlich abgeschaltet zu lassen.
Ganz genau. Ich will das Paging haben weil ich damit ne Menge Magie veranstalten kann aber ich will es nicht ständig benutzen müssen weil es Performance kostet. Wenn ich auf die Magie verzichte dann kostet das aber noch mehr Performance (z.B. atomares Verschieben von Segmenten ist IMHO ein absolutes KO-Kriterium).
Außerdem rede ich (für meine Begriffe) immer von Randbedingungen, seltenen Ereignissen - die zu optimieren bringt mMn wenig.
Das Defragmentieren soll natürlich möglichst selten vorkommen aber wenn es dann, wenn es gebraucht wird, nicht richtig funktioniert ist IMHO mein Konzept totaler Mist (mal abgesehen davon das die meisten Leute die Segmentierung eh als totalen Mist bewerten).
Grüße
Erik