Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - FlashBurn

Seiten: 1 ... 37 38 [39] 40 41 ... 43
761
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 20. July 2010, 16:49 »
Zitat von: taljeth
Auf einem Desktop wird das Bisschen niemanden jucken. Aber RT-Systeme stört es teilweise schon, dass im SMM Zeit verbraten wird.
Kommt halt wieder drauf an, wann es passiert. Wenn ich gerade einen HD-Film gucke und ACPI meint es müsste jetzt aus irgendeinem Grund mal die CPU schlafen legen oder runtertakten, dann dürfte der Film schon stocken. Das Beispiel ist jetzt insofern doof, weil ja die CPU arbeitet und auf dem Bildschirm tut sich ja auch was. Also dürfte ACPI da nicht auf solch eine Idee kommen.

Was mir da gerade noch auffällt, was hat der SMM jetzt mit meinem Timer zu tun? Die CPU läuft trotzdem weiter, genauso wie PIT/HPET und die anderen Sachen.

Zitat von: svenska
Womit du dann jegliche Form des Stromsparens abschalten kannst, richtig. Das geht im Übrigen auch per APM-Treiber (POWER.EXE kann das), dort kannst du das Gesamt-APM-System auch abschalten; zumindest auf diesem System.
Dann spricht diese "POWER.EXE" bestimmt APM übers BIOS an und das könnte ich zur Not auch machen.

Zitat von: svenska
Ich rede im speziellen von Geräten Anfang der 90er Jahre!
Problem ist jetzt, das es sich also um Prä-Pentium Systeme handelt und ich/man nicht weiß ob das dann auch auf die späteren Systeme übertragen wurde. Dann kommt noch hinzu das du vor dem Pentium sowas wie einen TSC nicht hattest und wie gesagt, die anderen Timer interessiert das nicht ob die CPU runtergetaktet ist.

Zitat von: svenska
Ja, für den PC... dem Menschen wird diese halbe ms bestimmt nicht auffallen. Außerdem passiert das in der Regel ja auch nicht ständig alle 10 Takte, dass das System für 10000 Takte steht, sondern unter gewissen Randbedingungen (Standby, Akkuladestand-Grenzwert erreicht, Bildschirmhelligkeitstaster betätigt, ...)
Und genau in diesen Randbedingungen kann ich dann mal auf die Genauigkeit verzichten ;) Weil brauchen tust du sie nur, wenn der Nutzer wirklich was macht, z.B. spielen, Film gucken oder ähnliches und dann dürften diese Sachen auch nicht auftreten.
762
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 19. July 2010, 22:05 »
Zitat von: svenska
Wenn das BIOS nun aber deine CPU unbenachrichtigt und ungewollt für 2ms abschalten kann, weil es selbst was tun will, dann ist deine Zeitgenauigkeit doch ohnehin fürn Popo. Das betrifft dann auch Systeme mit HPET.
Ich will ja nicht so aus der Haut fahren wie du, aber wenn sowieso alles "fürn Popo" ist, wozu dann der ganze Ärger ;)

Also CPU und HPET/PIT/ACPI-PMT (und auf neueren CPUs auch der TSC) laufen auch wenn die CPU irgendwie runtergetaktet oder abgeschaltet ist (bzw. wird das komplette Abschalten der CPU sowieso nicht gehen, weil es länger als 2ms dauern dürfte diesen Zustand zu erreichen und auch wieder aus ihm heraus zu kommen)!

Was APM betrifft, so kann dies im BIOS deaktiviert werden bzw. kannst du einstellen ob das BIOS eingreifen soll oder halt nicht.

Zitat von: svenska
Dieses System mit APM, dass die CPU runtergetaktet wird, wenn keine Bildschirm- oder Tastaturaktivität passiert, ist doch insofern sinnvoll, als dass bei Nutzeraktivität - also interaktiver Nutzung des Systems - die Leistung da ist, sonst aber sofort wieder Strom gespart wird.
Wie auch taljeth schon meinte, ist das "kaputt". Denn warum kann z.B. gerade keine Benutzeraktivität stattfinden? Vielleicht, weil der Nutzer darauf wartet das der PC fertig wird? Wenn dann auch noch die CPU runtergetaktet wird, dann dauert es ja noch länger und würde im Endeffekt heißen, du verbrauchst mehr Strom als wenn du die CPU nicht runtergetaktet hättest! Da ist also wirklich was kaputt ;)

Zumal viel interessanter wäre doch zu wissen, von was für Zeiten wir hier sprechen? Ich meine wird das gemacht, wenn der Nutzer mal 1s nichts macht oder erst nach 3Minuten? Das spielt dann nämlich schon eine Rolle.

Zitat von: svenska
Zweite Sache, betrifft neuere Systeme mit ACPI: Wie ich neulich auf irgendeiner Kernel-ML gelesen habe, haben moderne BIOSse ebenfalls im Zusammenhang mit Stromsparmodi die Möglichkeit, jederzeit die CPU anzuhalten und/oder in spezielle Modi (SMBUS, ...) zu schalten. Und zwar für Dauern jenseits einiger Millisekunden! Unabhängig vom Betriebssystem! Damit meine ich nicht runtertakten, sondern Selbstverwaltung. Runtertakten kriegst du ja wenigstens noch mit, bzw. kannst du im Zweifelsfall drauf achten.
Auch hier gilt wieder, wenn das wirklich so passiert, fällt das dem Nutzer auf oder es passiert zu Zeiten, wo es eh keinen interessiert. Wenn es dem Nutzer aber auffällt und das System ständig "stockt", dann wird er das Gerät zurückgeben und die werden das ganz schnell wieder ändern! Denn mehrere ms sind für einen PC, besonders für einen modernen, ne halbe Ewigkeit!

Wenn du mal die Quelle nennen könntest, dann könnte ich mal nachsehen, was da wo und wann passiert.
763
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 19. July 2010, 13:56 »
Nochmal was zur Genauigkeit. Was mir vorallem wichtig ist, das wenn ein Thread 20ms schlafen möchte und du nur ne periodische Quelle für nen Timer hast (z.B. den PIT) mit einem Intervall von 15ms, dann schläft der Thread mindestens 30ms (eventuell sogar mehr). Genau hier wollte ich ansetzen, ob der Thread dann im Endeffekt 20,05ms oder 20,25ms geschlafen hat, ist mir erstmal egal (und sollte mehr oder weniger zu vernachlässigen sein).

Ich nehme ne nsek Auflösung weil es sich damit am einfachsten Rechnet und ich mir nicht alzu große Sorgen über schnelle CPUs (>4GHz) machen muss, ob ich die dann auch erreiche kann und will ich gar nicht garantieren (aber 10µs-Auflösung sollte eigentlich drin sein).

Zitat von: erik
Um genau zu wissen wie viele TSC-Ticks pro IRQ kommen solltest Du das mehrmals messen und zum anderen darfst Du niemals die IRQs abschalten oder andere langwierige (FPU-)Befehle ausführen die in diese Messungen nen Jitter reinbringen könnten ansonsten kannst Du Dir die ns-Aulösung auch gleich ganz sparen.
Ich weiß das meine Messung mit welcher Frequenz der TSC läuft nicht perfekt ist (ich bekomme auf einem AMD K6-200 ca. 197896???Hz), aber ich denke das ich mit der Genauigkeit leben kann. Eigentlich ist alles was genauer als 1ms ist doch schon verdammt gut, gerade auf solch alten System.

Zitat von: erik
Ein weiterer Punkt ist das Du zum umrechnen der TSC-Ticks in Nanosekunden (oder irgendeiner anderen fixen Zeitauflösung) definitiv Gleitkomma-Arithmetik benötigst und selbst dann noch Tricks brauchst um den Jitter beim periodischen TSC auslesen auszugleichen (die einzelnen Taktfrequenzen werden nicht vom selben Quarz erzeugt Du musst also mit minimalen Geschwindigkeitsunterschieden rechnen die möglicherweise erst nach längerer Laufzeit sichtbar werden).
Also was das umrechnen betrifft, da nutze ich im Moment 64bit und halt nsek-Auflösung (oder sogar PSec, da bin ich mir gerade nicht sicher) und das sollte auch ohne Gleitkommazahlen reichen.

Meinst du mit den verschiedenen Taktfrequenzen PIT und TSC? Was den Unterschied betrifft, ich nutze für die langfristige Zeimessung im Endeffekt nur den PIT, daher ist es mir egal wie sehr der TSC und der PIT auseinandertriften! Zumal ich ja immer nur eine Differenz nutze, von daher summiert sich doch ein vorhandener Fehler nicht auf.

Zitat von: erik
Nein, damit kennst Du zwar wieder den aktuellen Wert des schnellen Counters aber seine Zählgeschwindigkeit kennst Du nur wenn Du über mehrere exakt getimmte (also jitterfreie und das dürfte bei normaler SW-Nutzung quasi unmöglich sein) Auslesungen den Counterwert beobachtest und genau diese Zählgeschwindigkeit brauchst Du ja damit Du auch einen Nutzen aus dem schnellen Counter ziehen kannst.
Also in meinem Bootloader berechne/messe ich die Frequenz des TSC mit Hilfe des PITs (in einer Zeit von 110ms wimre). Da passiert außer einer Schleife wo "hlt" (was eventuell stören könnte) ausgeführt wird und dem PIT-Interrupt (wo nur ein Counter inkrementiert wird) nichts.

Zitat von: erik
Noch eins: selbst wenn Du alle obigen Probleme lösen solltest bleibt das der TSC keine IRQs generieren kann. Wenn ein sleep(20) auch wirklich exakt 20ms dauern soll bleibt also nur aktives Warten.
Hier kommt doch wieder mein toller One-Shot-Scheduler ins Spiel ;) Mit Hilfe des Counters und diesem Scheduler kann ich, mehr oder weniger, genau die Threads wieder aufwachen.

Zitat von: erik
Ob an den obigen Problemen der ACPI-PMT noch was bessert kann ich nicht sagen, den kenne ich nicht da ich mich nur sehr oberflächlich mit ACPI beschäftigt habe. Kann der ACPI-PMT Interrupts generieren? Zumindest gibt es diesen nur ein mal aber er ist wohl auch wieder über langsame I/O-Ports angebunden und da die Arbeitsfrequenz nur etwa das doppelte der vom PIT ist solltest Du Dir genau überlegen ob der Aufwand sich überhaupt lohnt.
Ich verstehe nicht ganz was du mit Aufwand meinst? Ich meine entweder ich machen nen "_rdtsc()" oder ich mache nen "ind(ACPI_PMT_PORT)".
Unterschiedlich sind nur, dass das Auslesen des PMT länger dauert, aber dafür kann ich ihn einfach und ohne Probleme auf SMP-Systemen verwenden. Ansonsten sind sie mehr oder weniger gleich. Beide machen nicht mehr als einen Counter zur Verfügung zu stellen, nur muss ich den PMT nicht ausmessen, sondern weiß wie lange ein Tick dauert.

Zitat von: erik
Am Anfang dieses Threads hab ich doch ein schönes Konzept beschrieben das einfach und zuverlässig funktioniert und mit PIT zwar auskommt aber auch vom HPET profitiert.
Ich will nicht unhöflich sein aber ich habe das Gefühl das Du Dich da in ein unerreichbares Ziel verrannt hast.
Ich seh das nicht als unhöflich an, ist nur ne Motivation dich mit noch besseren Argumenten von meinem System zu überzeugen ;)
Aber mal ehrlich, ich finde so doll unterscheiden sich die beiden Systeme nicht, dein Intervall ist kürzer (1ms : 55ms/62,5ms). Wenn man es nur so betrachtet ist es, mehr oder weniger, gleich. Ich nutze halt noch ne 2. Quelle um auch Events innerhalb des Intervalls auslösen zu können.

Um nochmal auf die SMP-Systeme zurück zu kommen. Ich weiß jetzt nicht ab wann man davon ausgehen kann das solche Systeme ACPI haben, aber selbst wenn nicht, dann denke ich mal das dort auf keinen Fall die CPU irgendwie runtergetaktet wird. Da ich den TSC beim initialisieren meines Kernels auf allen CPUs synchronisiere sollte es da eigentlich keine Probleme geben (die dürften auf solch alten Systemen auch noch nicht auseinandertriften). Ich möchte meinen das mit dem auseinandertriften ist erstmals so richtig auf AMD K7 SMP-Systemen aufgefallen.

Edit::

Ich habe gerade mal meine Berechnung wie lange ein TSC-Tick dauert ein wenig verändert und siehe da ist schon genauer. Auf einem AMD K6-200 bekomme ich 200440990Hz und auf einem Celeron 400 bekomme ich 401767778Hz. Die Werte habe ich jetzt jedesmal (ich habe jeweils 3mal getestet) bekommen. Wenn ich an einer Konstante noch ein wenig Pfeile, dann komm ich vielleicht sogar noch genauer hin. Jedenfalls sollte die Genauigkeit meiner TSC-Messung in Ordnung gehen und sie funktioniert bis zu einer Taktfrequenz von 1000GHz!
764
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 18. July 2010, 21:06 »
Zitat von: svenska
Mal abgesehen scheinst du mit der Grundidee eine Auflösung garantieren zu wollen, die du aber nicht einhalten kannst. Sowas ist bei nem Realtime-System tödlich; für dich wahrscheinlich eh egal.
Ich sag mal alles unter 1ms ist doch schon gut, wie genau es dann unter 1ms wird, ist doch erstmal zweitrangig.
Um es genauer zu sagen ist es mir wichtig, wenn ein Thread in 55ms aufgeweckt werden will, das er auch in annährend 55ms aufgeweckt wird (nur mal so als Bsp.) und nicht erst in 60ms.

Zitat von: svenska
Für Zeitmessungen nicht. Wenn du davon dann allerdings deinen Scheduler abhängig machst und der TSC unter Umständen nicht nur stehen bleibt, sondern sogar kaputtgeht, kannst du große Probleme mit dem Scheduling kriegen, wenn du damit nicht rechnest.
Genau das hält mich im Moment noch davon ab, diesen Counter auch im Scheduler zu nutzen. Denn das "witzige" daran ist, der eigentliche Grund ihn zu nutzen ist der PIT. Es wäre halt viel schneller den Counter zu lesen als den PIT und ich rede hier von 2496ns, hört sich erstmal nicht nach viel an, aber wenn man das pro Scheduleraufruf sparen kann, so summiert sich das nach einer Weile ganz schön auf. Um jetzt nochmal auf das "witzige" zu kommen, wenn ich den PIT nicht mehr nutze (also dann den APIC), dann habe ich (mit Ausnahme von ein paar alten SMP-System) eigentlich auch den ACPI-PMT zur Verfügung und brauche den TSC nicht nutzen.

Zitat von: svenska
So einfach ist es, denke ich, nicht. Das BIOS kann ja an sich garnicht feststellen, ob die CPU nun fleißig arbeitet oder nicht - solange es nicht explizit aufgerufen wird. Auf einem Notebook, was ich hier habe (Highscreen 486SX25, ist aber ein SL-Typ) wird die Aktivität an Bildschirm- und Tastaturaktivität gemessen, und zwar ausschließlich! Neben HLT gibt es ja keine CPU-internen Inaktivitätsbefehle.

Das bedeutet, dass ein Prozess unter DOS, wenn er keine Bildschirmausgaben macht und nur rechnet, die CPU in den 2 MHz-Modus schaltet, wenn das Power Management im BIOS aktiviert ist; gleiches gilt im Übrigen unter Windows 95. Auf einem Pentium habe ich dieses Verhalten auch schon einmal beobachtet, bin mir aber nicht mehr sicher.
Wenn das so ist, dann nehme ich darauf erst recht keine Rücksicht! Denn das System funktioniert ja ohnehin nicht wirklich.

Zitat von: svenska
Ich würde dem TSC - je nach Prozessortyp - im Allgemeinen keine langfristige Monotonie oder Stabilität zutrauen.
Hier habe ich das Gefühl das du mich, genau wir erik auch, nicht ganz verstanden hast.

Der TSC wird nicht für langfristige Monotonie genutzt. Im Endeffekt musst du dir mein System so vorstellen als wenn du nur eine periodische Quelle (RTC/PIT) hast, die mit nem, verhältnismäßg, langem Intervall (>=55ms) läuft. Diese Quelle ist langfristig gesehen genau! Um jetzt aber auch die Zeit innerhalb dieses Intervalls genau zu kennen, nutze ich eine andere Quelle (TSC/ACPI-PMT).

Als mal als Bsp. die periodische Quelle macht bei jedem Aufruf des Handlers:
highPrecisionCounter+= nsecsPeriodicSourceIntervall;
timeLastInt= _rdtsc();
Wenn du jetzt den aktuellen Wert des Counters haben willst machst du das:
returnVal= highPrecisionCounter + (_rdtsc() - timeLastInt);

Damit erreiche ich das mit jedem Aufruf des Interrupthandlers der Wert des Counters wieder genau ist, egal was dazwischen mit dem TSC passiert ist!

Ich hoffe du hast es jetzt verstanden. Im Endeffekt nutze ich den TSC um "kurze" (<=62,5ms) Zeiten zu messen.

Zitat von: svenska
Wäre es da nicht sinnvoller, den Thread selbst den Aufweckzeitpunkt bestimmen zu lassen?
Auch hier hast du mich nicht ganz verstanden.

Ich meinte damit, dass der Thread die Sleep-Funktion aufruft (wo er als Parameter, die Zeit die er schlafen will angibt), ich den aktuellen Wert des Counters (siehe Oben) hole und darauf die Zeit die er schlafen will drauf rechne und damit weiß zu welchem Zeitpunkt ich ihn wieder aufwecken muss.
765
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 18. July 2010, 13:50 »
Zitat von: svenska
Naja, und dann stelle ich mir halt noch die Frage, warum du auf so einem (langsamen) System einen Couter mit nsek-Auflösung überhaupt brauchst; bei allem, was irgendwie größer als klein ist (Browser, Officepaket, Mediaplayer) kannst du eh nicht mit der geforderten Latenz darauf reagieren. Und wenn du ein richtiges Real-Time-Betriebssystem schreiben möchtest, dann ist das ohnehin nur ein sehr kleiner Teil des Gesamtpaketes.
Naja, ich wollte halt ne Auflösung die <1ms ist ohne das ich nen periodischen Timer dafür nutze. Auf die nseks bin ich gekommen, weil es eine gute Auflösung auch für aktuelle Systeme ist und ich mir so die Arbeit am HAL (Hardware-Abstraction-Layer) vereinfachen wollte.

Zitat von: svenska
Bedenke die Konsequenzen, was passiert schlimmstenfalls, wenn dein hochpräziser Counter groben Unfug enthält? Und denke auch daran, dass du bei _jeder_ Nutzung darauf Rücksicht nehmen musst. Wenn du nämlich dein Gesamttiming auf diesen Counter irgendwie aufbaust, wird das dir später böse in den Rücken fallen - möchtest du das Teil nur für kurzzeitige, exakte Messungen nutzen, reicht der TSC auch direkt aus und du sammelst dir keine Probleme ein.
Im Moment schätze ich die Probleme als nicht so schwerwiegend ein (noch ;) ). Denn es kann "nur" zu Problemen innerhalb des Intervalls von 62,5ms (RTC) bzw. 54ms (PIT) kommen. Denn mit jedem Interrupt einer der beiden Timer, stimmt der Wert des Counters wieder ab dem Zeitpunkt. Wenn ich später wirklich feststellen sollte, dass das Intervall zu groß ist, könnte ich es immernoch verkleinern. Aber wie du selbst schon gesagt hast, braucht man "eigentlich" die hohe Auflösung auf solch alten Systemen nicht, also dürfte das etwaige "stoplern/stocken" auch kein Problem darstellen.

Zitat von: svenska
Vielleicht findest du in den Dokumenten zum i386SL/i486SL Informationen zum Power Management. Ich kann mich jedenfalls nicht daran erinnern, dass das beim Pentium groß beworben wurde; ich vermute, es wurde einfach von den Vorgängern übernommen.
Genau die Dokumente (vom 486) hab ich mir angeguckt und konnte leider nichts konkretes finden bzw. das was ich gefunden habe, legt nahe, das der TSC komplett stehen bleiben kann. Der Punkt ist aber, dass das ja nur passieren kann wenn die CPU nichts zu tun hat und dann wiederum benutzt auch keiner den Counter und somit gibt es für mich kein Problem.
Denn so wie ich dich und das Dokument verstanden habe, gibt es nur Probleme mit dem TSC, wenn die CPU absolut gar nichts zu tun hat und dann wird, wie gesagt, auch mein Counter in dem Moment nicht gebraucht. Ab dem Zeitpunkt wo er dann vielleicht wieder gebraucht wird und die CPU wieder was zu tun hat, funktioniert das System ja auch wieder. Denn die periodischen Interrupts kommen immer, egal in welchem Zustand sich die CPU befindet.

Mich würde noch interessieren was du genau unter Gesamttiming verstehst, also was da deiner Meinung nach alles dran hängt?

Im Moment nutze ich das nur als Hoch-Präzisen-Counter und eventuell bald um festzustellen, wie lange ein Thread gelaufen ist. Ansonsten um den Zeitpunkt festzustellen, wann ein Thread sich schlafen legen möchte (um den Aufweckzeitpunkt zu errechnen).

766
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 18. July 2010, 07:24 »
@Svenska

Also ich habe deine Bedenken zur Kenntnis genommen. Ich weiß das der Pentium irgend so ein "SL Enhanced Power Management" hat, aber was das genau bedeutet konnte ich leider noch nicht finden.

Um mir meine Sache jetzt nicht unnötig schwer zu machen, nutze ich erstmal den TSC weiter. Im Moment ist das einzigste Problem was ich mir vorstellen kann, ein kurzzeitiges "stocken/stolpern" des Hoch-Präzisen-Counters. Der Vorteil ist ja, das er periodisch "synchronisiert" wird und damit etwaige Fehler des kleinen "zwischen"-Counters (TSC/ACPI-PMT) ausbügelt.

Wenn wir gerade schon beim TSC sind. Weiß jemand wie man bei Intel nachgucken kann (z.B. mittels CPUID) ob der TSC immer konstant aktualisiert wird? Ich weiß das es bei AMD dafür extra nen Flag bei CPUID gibt, habe aber bei Intel dazu noch nichts gefunden. Ansonsten müsste ich halt Family und Co auslesen und danach dann entscheiden ob ich ihn nutzen kann oder nicht.

@Offtopic

Weiß jemand ob man zu alten Sockel7 Zeiten das ACPI im BIOS aktivieren musste? Irgendwie findet mein Loader bestimmte ACPI Sachen nicht, obwohl diese vorhanden sein müssten (handelt ich um ein Board mit nem VIA MVP3 Chipsatz).
767
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 17. July 2010, 12:56 »
Um es kurz zu machen, implementiert war es 1 Tag nach dem Post ;)

Zitat von: erik
Ich habe ehrlich gesagt kaum etwas von dem verstanden was Du da schreibst. Vielleicht solltest Du mal die verschiedenen HW-Kombinationsmöglichkeiten (die Dein OS unterstützen soll) aufzählen und für jede einzeln und präzise erklären was Du genau vor hast.
Du wolltest es so ;)

Also ältere PCs haben kein ACPI (auf denen sollte dann der TSC 100%ig laufen), aber nen PIT und die RTC. Ich nutze also den PIT für meinen One-Shot-Scheduler. Die RTC wird im periodischen Modus (62,5ms) programmiert und inkrementiert immer nen Counter, aber was viel wichtiger ist, bei jedem Aufruf des Interrupthandlers (von der RTC) speichere ich den aktuellen TSC Wert.
So kann ich ganz einfach sagen, wieviel "Ticks" (welche man dann auch "einfach" in nsek umrechnen kann) seit dem letzten RTC Interrupt vergangen sind. Damit hab ich nen wirklich Hoch-Präzisen-Counter (je nachdem wie schnell die CPU ist).

Hat man dann nen PC mit ACPI, kann man den ACPI-PMT (Performance Monitor Timer, wimre) nutzen, anstatt des TSCs. Sprich das System bleibt das gleiche, ich nutze den PIT für den One-Shot-Scheduler und die RTC für nen periodischen Interrupt. Anstatt des TSC als Counter nutze ich aber jetzt den ACPI-PMT, womit ich Probleme durch runtertakten oder ähnliches umgehen will.

Hat der PC dann auch noch nen APIC, den ich nutzen kann, ändert sich das System ein wenig. Der APIC wird für den One-Shot-Scheduler genutzt. Diesmal nehme ich den PIT im periodischen Modus (55ms) anstatt der RTC. Ansonsten funkioniert es hier wieder genauso. Beim Interrupthandler des PITs wird der aktuelle Wert des ACPI-PMTs gespeichert.

Bei SMP-System findet das gleiche System wie oben Anwendung.

Wie funktioniert jetzt der Hoch-Präzise-Counter?

Wenn ich ganz genau bin, ist das nicht irgendein Counter, sondern der wird sogar in nsek geführt. Soll heißen, wenn man sich den Wert holt und 1000 bekommt und der letzte Wert den man sich geholt hat war 500, dann sind "Pi mal Daumen" 500ns vergangen.
Ich rechne auf meinen globalen Counter (wird über RTC oder PIT implementiert) immer genau die nsek drauf, wie zwischen 2 Interrupts liegen.
Will dann ein Programm den Wert des Counters haben, mache ich folgendes (vereinfacht):

uint64t counter= nsecscounter, perf= perfcounterRead(), last= timeLastInt;

if(flags & USING_TSC)
    return counter + ((perf - last) * tscTickNSecs);
else
    return counter + ((perf - last) * acpiPMTTickNSecs);
Natürlich behandle ich in meinem Code noch überläufe, was beim ACPI-PMT sehr wichtig ist (da er entweder bei 4 Sek (24bit) oder 1130 Sek (32bit) überläuft), aber das ist für das Bsp nicht wichtig.

Das zu implementieren ist/war nicht schwer, ist auch nicht wirklich viel Code. SMP-Safe ist das ganze auch noch, sprich ich brauche keine Locks dafür nutzen (den Fall das sich der Counter während des auslesens ändert oder halt der Wert von "TimeLastInt" beachte ich in meinem Code auch).

Wie gesagt sollte ich nun alle Probleme, Schwächen und sonstige Sachen ausgebügelt haben. Ich habe alles was ich wollte, nen One-Shot-Scheduler, nen Hoch-Präzisen-Counter und ich kann meine Threads für sehr kurze Zeiten (<1ms) und das ganze noch mit ne verdammt vernünftigen Präzision schlafen legen.

Wenn ich die Zeit und Lust (da ich es bisher nicht wirklich brauche) finde, werde ich auch noch den HPET nutzen.

Da bin ich mir dann aber noch nicht sicher wie ich es mache. Aufjeden Fall wird der HPET dann den PIT, in seiner Funktion, ersetzen, aber ob ich dann auf nen 3. Counter verzichte (also auf TSC oder ACPI-PMT) weiß ich noch nicht. Am liebsten würde ich dafür dann wieder den TSC nutzen, was auf neueren CPUs ja wieder ohne Probleme möglich ist. Das hätte halt den Vorteil, das ich nicht ständig den HPET auslesen müsste (zwecks Counter-Wert) und ich würde so eine noch höhere Auflösung (da der TSC, wenn er an die CPU Frequenz geknüpft ist, ja ne verdammt hohe Freq hat) bekommen. Mal ganz davon abgesehen, dass das Auslesen des TSCs wohl schneller sein dürfte als das Auslesen des HPETS.

Ich hoffe ich war präzise genug, wenn nicht, wie gehabt, einfach fragen!

Edit::

Mir ist noch ein wunderbarer Vergleich eingefallen. Im Endeffekt entspricht das System einer Uhr mit Stunden- (periodischer Interrupt -> RTC/PIT) und Minutenzeiger (Counter -> TSC/ACPI-PMT) ;)
768
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 13. July 2010, 20:34 »
So ich melde mich auch mal wieder und möchte mal wieder was zum eigentlichen Topic beitragen.

Da ich mal wieder Zeit gefunden haben ein wenig an meinem System zu arbeiten und ich mich auch endlich mal mit der 3D-Programmierung befassen will, ist mir wieder eingefallen wozu man nen "High-Performance-Counter" braucht.
Bei Spielen möchtest du ja das sich die Spieler-Figur auf jedem Rechner (egal wie schnell oder langsam) gleich schnell bewegt. Dazu benutzt man solch einen "High-Performace-Counter". Um sagen zu können, so seit dem letzten Zeichnen ist ne bestimme Zeit vergangen und die Spielerfigur bewegt sich damit jetzt ne bestimmte Anzahl von "Pixeln".

Problem ist nun natürlich, wie implementiert man solch einen Counter im System. Ich habe nochmal ein wenig gesucht und habe jetzt hoffentlich nen brauchbares System dafür gefunden.

Ich werd dafür ne Kombination aus dem ACPI-PMT und dem PIT bzw. wenn möglich den TSC nehmen.

Den ACPI-PMT kann ich natürlich nur nutzen wenn ACPI auch vorhanden ist (da mein System ja auch PCs unterstützt die kein ACPI haben). Ist das System aber so alt das es kein ACPI hat, dann sollte ich davon ausgehen können das ich ohne Bedenken den TSC nutzen kann (ist dem so? konnten sich die CPUs damals schon runtertakten?).
Warum will ich den ACPI-PMT in Kombination mit dem PIT nutzen? Also erstens einmal gibt es das Problem das je nachdem wie der PMT implementiert ist, der Counter entweder 24bit oder 32bit groß ist. Er läuft also alle 4Sek oder alle 1130Sek über. Nutze ich diesen Counter jetzt in Kombination mit dem PIT, so erspare ich mir auch ständig den PIT lesen zu müssen (was ja ein Problem mit meinem System ist), da ich einfach bei jedem PIT-IRQ den Counter auslese und abspeichere. Will ich dann wissen wieviel Zeit seit dem letzten PIT-IRQ vergangen ist, brauche ich einfach nur den PMT auslesen und die Differenz zw dem aktuellen Wert und dem gespeicherten Wert ausrechnen (da kann ich dann auch relativ einfach den Überlauf behandeln). Desweiteren sollte ich damit auch das Problem umgehen, das der PMT wohl auch mal 4Sek oder mehr abtriftet (da ich ja immer nur die Differenz zw 2 Werten nehme und nicht den Counter nutze um die Werte aufzuaddieren).

Was den TSC betrifft, so würde ich diesen genauso benutzen wie den PMT.

Habe ich einen solchen "High-Performance-Counter" kann ich auch mein Event-System (also das mit "tickless"-Timer) einfacher umsetzen.

Optimal läuft das ganze natürlich erst mit dem HPET. Obwohl ich mal behaupte das ich so eigentlich alle Probleme der vielen Timer umgehen sollte. Das einzigste was ich dann nicht mehr machen kann, ist den PIT (als periodischen Timer) abschalten, wenn keine Events vorhanden sind. Denn ich möchte ja jetzt über diesen auch die Systemzeit und den "High-Performance-Counter" implementieren. Ich denke aber das ich damit leben kann ;)

So bin für Meinungen offen und bitte auch etwaige Fehler die in dem System stecken nennen!
769
Lowlevel-Coding / Re:Parallel Port Treiber
« am: 07. July 2010, 20:14 »
Versuchs mal auf dieser Seite:

http://www.beyondlogic.org/
770
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 24. June 2010, 22:50 »
Zitat von: erik
Nur mit dem PIT alleine ist das mMn unmöglich (entweder ist man auf eine konstante/niedrige PIT-IRQ-Frequenz festgelegt oder man verliert die Langzeitgenauigkeit wenn man immer wieder am PIT rumdreht), und wenn Du noch einen/mehrere Local-APIC-Timer benutzt kannst Du zwar theoretisch eine höhere Genauigkeit bekommen hast aber auch Probleme weil diese zwei Systeme nicht exakt Synchron sind und langsam aber sicher auseinander driften.
Ahhh ;)

Deswegen nutze ich ja immer 2 Timer, einen der "tickless" läuft und einen der periodisch läuft, aber die Periode ziemlich lang ist (im Falle des Gespanns APIC/PIT 55,4ms) bzw. theoretisch wenn kein periodisches Event läuft, kann er (der periodische Timer) abgestellt werden.

Da das alles in meiner Freizeit als Hobby läuft mach ich es sowieso so, dass ich meine Idee implementiere und wenn ich dann irgendwann später feststelle die Idee war doch nicht so gut oder hat noch Lücken, dann bessere ich halt nach. Soll heißen ich habe mir keinen Plan für meine Entwicklung gemacht und ich überlege mir nicht schon vorher wie alles hinterher aussehen soll. Dadurch dauert es manchmal etwas länger bzw. muss oft Code komplett neu geschrieben werden, aber es geht schneller (was in dem Fall sehr relativ ist ;) ) voran.

Zitat von: erik
Das hat nichts mit ARM oder MIPS oder anderen CPU-Architekturen zu tun. Bis jetzt gibt es nur eine Firma die gute ARM-Systeme erfolgreich anbietet aber leider machen dort bestimmte Management-Entscheidungen, die die zugehörige Software betreffen (oder fehlende HW-Schnittstellen), diese Produkte für einen mündigen Käufer quasi gänzlich indiskutabel.
Ich gehe mal davon aus du redest von Apple.

Nachdem was ich in letzter Zeit so in verschiedenen News gelesen habe, ist das Interesse an ARM System, besonders an Servern (im Hinblick auf den Energieverbrauch) aber groß genug.
Sagen wir es doch so wie es ist. Linux als alleiniges Betriebssystem verkauft sich nicht für die Masse und Windows gibt es nicht vernünftig für die ARM CPUs (von den Mobile Versionen mal abgesehen).

Was ich an den MIPS zu bemängeln hatte, war aber das die ja schon Netbooks herstellen und selbst die OpenBSD Entwickler gesagt haben, das sie nicht alle Work-Arounds implementieren werden und MIPS ist jetzt nicht gerade ne niegel nagel neue Architektur. Ich kenne mich da zwar leider auch nicht aus, aber ist es da nicht wie bei ARM, soll heißen du kaufst so zu sagen "Pläne" und kannst dann deine eigene CPU zusammen basteln?!

Naja, ich hoffe das bald ARM-Systeme in großer Stückzahl zu finden sein werden (im Net/Notebook und PC Segment). Wenn ich das Geld hätte, würde schon längst so ein schickes BeagleBoard bei mir zu Hause stehen!
771
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 23. June 2010, 22:34 »
Zitat von: erik
Ich finde Dein Konzept immer noch irgendwie unnötig kompliziert. Wenn Du keine genaue Hardware zur Verfügung hast (also keinen HPET) dann kannst Du auch kaum genaues Timing für die Applikationen anbieten. Mit den Tricks legst Du Dir meiner Meinung nach nur ein faules Ei ins Nest, also Komplexität deren Nutzen in Relation zum Aufwand wahrscheinlich viel zu klein ist.
Kompliziert ist es bzw. wird es immer mehr, desto mehr Probleme ich "ausbügeln" muss ;)
Das Ziel ist es auch ohne HPET ein annährend genaues Timing zu haben. Dass das ganze kompliziert wird war mir klar.

Zitat von: erik
... Mich würde dazu mal interessieren wie andere OSe das lösen.
In dem Sinne, gar nicht! Wenn du einen periodischen Timer nutzt ist die untere Grenze genau 1 Tick (im Falle von Windows 10ms oder 15ms). Ansonsten haben sich die jeweiligen Programmierer die kleinere und/oder genauere Events benötigten eben anderes beholfen. Z.B. indem das Video am Audio synchronisiert wird.
Ab Vista wird dann sogar der HPET genutzt (unter XP wird er zwar erkannt, aber nicht genutzt).

Wie das ganze unter Linux läuft weiß ich nicht, aber da auch Linux mal nen periodischen Timer hatte, gehe ich mal davon aus, dass für diesen Timer das gleiche gilt wie unter Windows.
Wie sie das dann mit dem tickless Timer gelöst haben müsste man auch nachgucken.

Was die MIPS Platform angeht. Nach dem was ich da gerade auf deinem Link gelesen habe, war das nicht gerade ein toller Start. Ich meine Hardwarefehler, welche ich dann umgehen muss, sonst friert das System ein. Auf solche Spielchen wollte ich mich eigentlich nicht einlassen. Dann lieber eine ARM-CPU, aber auch bei der ist das Problem, die werden zwar seit Jahren angekündigt, aber auf dem Markt kommen sie nicht wirklich an!
772
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 17. June 2010, 00:00 »
Um das Thema mal wieder zu beleben habe ich mir in letzter Zeit mal Gedanken gemacht, wie ich das Problem mit dem Jitter bei periodischen Events die kleiner (von der Zeit her) sind als der periodische Timer (im Falle des PIT <55,4ms).

Ich habe mir überlegt, das von den periodischen Events immer so viele "Kinder" von dem Event erstellt werden (und damit auch in die Queue wandern) das genau ein Kind soweit in der Zukunft liegt, das es in der Queue des periodischen Timers liegt. Damit bleibe ich auf lange Sicht Konstant, kann aber trotzdem die Events die zwischen zwei Ticks von dem periodischem Timer liegen, sehr genau feuern lassen.

Soweit so gut. Das Problem was jetzt aber kommt ist, dass man damit das System ganz leicht in die Knie zwingen kann, indem man einfach eine sehr kleine Periode nimmt (z.B. 20µs = 2770 "Kinder"-Events).

Ich sehe da jetzt 2 Lösungen, einfach ignorieren und hoffen das keiner auf die dumme Idee kommt oder die Zeit für eine Periode einschränken.

Auf der einen Seite möchte ich das man das System nicht so leicht in die Knie zwingen kann, aber auf der anderen Seite möchte ich es auch nicht künstlich beschränken. Obwohl scheinbar bisher niemand eine solch kleine Periode benötigt hat.
773
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 10. May 2010, 10:44 »
Zitat von: erik
Ein abgelaufener Timer kann prinzipiell maximal nur 1 Kind haben und ist damit garantiert immer mit wenig Aufwand zu löschen.
Da kann ich nur sagen, du solltest dich noch ein wenig mit solch ausbalanzierten Bäumen beschäftigen ;) Denn es ist in dem Sinn egal wieviel Kinder ein Knoten hat, ob der Baum danach ausbalanziert werden muss, dass ist die entscheidene Frage. Ich würde dir ja den AVL-Baum als einstiegs Lektüre empfehlen, da ich ihn einfacher zu verstehen finde.

Zitat von: erik
Gerade das wird mit dem PIT-One-Shot-Modus nicht klappen weil ja der PIT immer wieder neu zeitaufwändig konfiguriert werden muss. Nach genau 360000 Bildern wird mit der PIT-One-Shot-Methode sicher etwas mehr Zeit als ganz exakt 4 Stunden vergangen sein. Wenn Du das anders siehst dann erkläre mir das bitte mal genauer.
Den Vorteil den ich beim PIT und periodisch sehe ist, dass du genau sagen kannst wie der Jitter aussieht. Das ist bei der One-Shot Methode nicht möglich.
Ich denke mal das du immernoch mit deinem absoluten Zeiten rechnest ;) Wenn ich aber relative Zeiten nehme, dann ist der Jitter, der vor dem aktuellen Zeitpunkt aufgetretten ist, egal! So wird es ihn zwar geben, aber er summiert sich nicht auf.
Was mir aber gerade aufgefallen ist, das ich mir mit den 40ms selbst ein Ei gelegt habe ;) Denn dieser Timer wird immer in der Sleep-Queue der CPU bleiben (und dummer weise sogar immer auf der selben CPU, was aber nicht bedeutet das der Thread der das Event abfragt immer auf der selben CPU läuft).

Zitat von: erik
Bei einer PIT-Periode von 15ms dürfte der Jitter für ein 25Hz-Timer zwischen 0ms und 10ms liegen. Wie Du da auf 20ms kommst verstehe ich nicht.
Gut, auch da fällt mir gerade auf, das der Jitter den ich meine nur beim 1. Mal auftritt. Denn best-case wäre, wenn der Thread dieses Event kurz bevor der PIT feuert erstellt, aber der worst-case wäre, wenn der Thread kurz nach dem der PIT gefeuert hat, das Event erstellt. Ich hoffe du kannst nachvollziehen wie ich das meine. Das Problem ist die "lange" Periode von 15ms. Du kannst ja schlecht wissen ob das Event am Anfang oder am Ende der Periode erstellt wird, aber der Wert des Counters, der absoluten Zeit, ist der selbe!

Zitat von: erik
Schon klar, ich verstehe das Du Präzision willst, geht mir genau so. Aber Du solltest erst mal klar definieren was Du unter Präzision verstehst. Willst Du das ein Film mit 216048 Frames bei 24fps genau 2:30:02 geht oder was möchtest Du?
Ich muss dir ganz ehrlich sagen, das ich wo ich das System "entwickelt" habe, mir gar keinen Kopf über periodische Sachen gemacht habe, sondern mir war wichtig das wenn ich nen sleep(10) aufrufe, das so genau wie möglich sein sollte. Das will ich auch immernoch, aber ich muss halt mit den Nachteilen dieses Systems für periodische Sachen leben. Obwohl ich ja finde das durch mein 2-geteiltes System der Jitter ganz gut abgefangen wird.

Zitat von: erik
Echt? Ich bin geschockt! Das hätte ich im 20 Jahrhundert der x86-Plattform nicht mehr zugetraut das es noch HW gibt die so lange Bedenkzeit nur für sich selbst braucht. Die APICs haben doch keine nennenswerten externen Abhängigkeiten, wofür benötigen die mal einfach so Zeit? Kannst Du nicht alle APs gleichzeitig aktivieren?
Problem ist, du sollst dem APIC Zeit geben, so dass er die Nachricht verschicken und die anderen CPUs diese auch empfangen können. Ich könnte alle APs gleichzeitig aktivieren (was ich in einer alten Version auch gemacht habe), aber das kann zu Problemen führen (auch wenn das sehr unwahrscheinlich ist). In dem Standard von ACPI und MPS ist vorgesehen, dass ne CPU auch als defekt vom BIOS markiert werden kann und diese CPU willst du nicht starten! So sage ich, lieber ein wenig mehr Zeit beim Starten der APs verbraten und dafür alle Eventualitäten aus dem Weg räumen!
Das Problem sind hier im Endeffekt halt auch wieder die alten Systeme. Wenn ich mich recht erinnere, dann wurde das busy-Flag im x2Apix-Mode entfernt, du brauchst dir da also keine Gedanken mehr machen, ob die Message verschickt wurde oder nicht (und brauchst somit auch nicht mehr warten).
Das "lustige" ist, man sollte lieber zu lange Warten als zu kurz. Denn ich hatte schon den Fall, das mein OS auf nem neuem Core2Duo PC alle Kerne starten konnte, aber auf nem alten Dual P3 System konnte mit einmal die 2. CPU nicht mehr gestartet werden. Als ich dann die Zeit zum Warten verlängert hatte, lief wieder alles.

Zitat von: erik
Das klingt für mich viel aufwändiger als es IMHO eigentlich nötig wäre. Du schreibst in den Local-APIC-Timer ja 2 verschieden Dinge rein, das finde ich persönlich verwirrend und möglicherweise etwas fehleranfällig. Was ist wenn kein APIC vorhanden ist?
Wieso und wo schreibe ich 2 Dinge in den APIC? Jeder Timer der nen Counter hat kann so benutzt werden (also auch der PIT).

Zitat von: erik
Auch das erscheint mir unnötig kompliziert. Außerdem gibt es dann eine 2 Klassengesellschaft bei den Timern: solche die kürzer sind als diese 55,4ms und recht genau laufen und jene die länger als 55,4ms laufen und auf ein 55,4ms-Raster gedrückt werden (also wohl mindestens 110,8ms). Wie willst Du eigentlich den Startzeitpunkt eines Timers ermitteln (also den Moment wo z.B. ein sleep(20) aufgerufen wurde) um zu ermitteln ob er noch vor dem nächsten 55,4ms-Tick abläuft oder erst danach. Wenn Du nur diese 55,4ms-Ticks hast dann hast Du auch keine genauere absolute Zeitbasis, kannst also den Timer-Start auch nur auf 55,4ms genau bestimmen. Oder hab ich was übersehen? Oder war das die Idee mit dem auslesen des aktuellen PIT-Zählerwertes und diesen quasi als zusätzliche Genauigkeit (das meinte ich mit dem Nachkomma-Bits) zu benutzen?
Du hast mich leider immernoch nicht richtig verstanden :(

Also zum ermitteln des genau Zeitpunktes (was leider im Falle des PITs "nur" auf 3*832ns genau wird) nutze ich den Wert des Counters! Also das was du vermutlich mit den Nachkomma-Bits meinst.

Nun zu meiner 2-Klassengesellschaft. Ich habe 2 Queues, eine für Timer >55,4ms und eine für Timer <= 55,4ms.
Wir lassen die periodischen Timer jetzt mal außen vor. Ich habe also einen Thread der will 100ms schlafen. D.h. er kommt auf jeden Fall erstmal in die Queue mit den Timern >55,4ms. Aber nach einem Tick (ich ignoriere die genaue Zeit jetzt mal um es einfacher zu machen) will der Timer ja nur noch 44,6ms warten und d.h. er wird aus der Queue für Timer >55,4ms entfernt und wird in die Queue <=55,4ms gepackt.

Ich hoffe du siehst nun das die Timer früher oder später alle in der Queue <=55,4ms landen und auch nur dort ausgelöst werden können. Die Queue für Timer >55,4ms ist nur dafür da um den Jitter so klein wenig möglich zu halten.

Zitat von: erik
Darf ich Dich an die vielen Smart-Phones erinnern? Es gibt einiges an tollen Nicht-x86-Systemen die für die normalen PC-Arbeiten absolut geeignet sind, z.B. verschiedene NetBooks mit ARM- oder MIPS-Innenleben. Das Problem, welches die Hersteller von einer aktiven Vermarktung abhält, ist einfach das kein Windows (und oft auch kein Flash) drauf läuft. Ich persönlich betrachte beides eher als Vorteil und nicht als Nachteil und hoffe das Android ein Erfolg wird und damit dann die Windows-Pflicht, die viele Hersteller empfinden, deutlich reduziert wird. Mit der Abkehr von Windows kann dann auch eine Abkehr von x86 erfolgen, ich denke beides wird langsam aber sicher an Bedeutung verlieren aber wohl auch nicht ganz verschwinden.
Wie gesagt, Smart-Phones gehören nicht wirklich zu meinen Zielen! Zumal das OS-Deving schon kompliziert genug ist. Wenn ich mich dann auch noch damit auseinander setzen muss wie ich mein OS auf ein solches Smart-Phone bekomme und dann müsste ich noch Reverse-Enginering bertreiben, da die Platformen nicht offen sind und von den vielen total unterschiedlichen Platformen will ich erst gar nicht anfagen. Das wäre einfah nur der absolute Overkill!

Was Windows betrifft, glaube ich nicht das es je komplett verschwinden wird. Dann gibt es halt nen Windows für die anderen Platformen!

Wo gibt es denn diese Netbooks für normale Menschen (und zu normalen Preisen) zu kaufen? Die ARM-Netbooks werden zwar ständig angekündigt, aber kommen tut da nicht wirklich was und von MIPS-Netbooks habe ich noch gar nichts gehört.

Zitat von: erik
Hast Du schon was vom iPad gehört? Die Restriktionen, die Apple künstlich einbaut, finde ich zwar ganz und gar nicht toll (deswegen werde ich wohl nie ein iPad besitzen) aber die Hardware als solche ist schon ziemlich gut (von ein paar fehlenden Schnittstellen abgesehen, die aber gewiss ganz leicht zu integrieren wären). Für ein paar Euro mehr wäre sicher auch Dual-Core und ordentlich RAM möglich, die nötigen Komponenten gibt es jedenfalls. Was der ARM-Plattform fehlt ist der Schritt in Richtung 64Bit. Das haben MIPS und PowerPC schon lange (schon vor x86) und erfolgreich (beide waren schon im High-Performance-Computing vertreten) erledigt und würden sich daher auch für dicke PCs empfehlen. Man darf also gespannt sein was die Zukunft so bringt.
Das iPad ist ja gut und schön (nicht wirklich ;) ), aber wie gesagt, die ganzen Beschränkungen und wer wirklich im Internet surfen will und da schließe ich das Mailschreiben, Forumsbeitragschreiben und Blogschreiben mit ein, der kommt einfach nicht ohne eine Tastatur aus. Zumindest möchte ich nicht solch langen Beiträge wie hier mit ner Tastatur auf nem Touchdisplay schreiben!
Ich kann zwar auch nicht in die Zukunft sehen, aber ich behaupte mal wenn Intel x86 überall haben will, dann bekommen die das auch hin! Ob du gut ist, sei mal dahin gestellt.

Das gleiche Problem gibt es momentan beim Auto. Ein Elektromotor ist was die Effizienz betrifft nem Benzin/Diesel-Motor sowas von überlegen, aber wen interessierts? Das selbe damals beim Video-System (VHS und Beta2000 oder so ähnlich). Wir leben im Kapitalismus und der normale Mensch ist dumm wie Knäckebrot (um es mal ganz überspitzt zu sagen). Der kauft was ihm die Werbung sagt und wer hat die beste Werbung, nicht zwangsläufig der mit dem besten Produkt, sondern der mit dem meisten Geld! Und Intel hat verdammt viel Geld.

Also aus meiner Sicht ist das Netbook ein verdammt gutes Bsp, das es egal ist wie gut oder schlecht ein Produkt ist (Apple fällt da auch rein ;) ). Ich kann mit den Dingern nichts Anfangen. Denn zu wenig Leistung und am Anfang viel zu kleiner Bildschrim. Ich bin Brillenträger und möchte nicht das meine Augen noch schlechter werden (bezieht sich auf bestimmte "hohe" Auflösungen auf nem viel zu kleinem Bildschirm).

Das Problem eines wirklich guten Produktes ist doch, es muss auch ne Firma mit entsprechenden finanziellen Mitteln dahinter stehen. Denn wenn PowerPC so toll wäre, warum haben wir den dann heute nicht im Mainstream bereich (ich weiß das sie im Serverbereich ganz gut sind)?

Das selbe wurde auch in nem anderem Forum diskutiert. Da ging es darum warum so wenig DAUs AMD wollen. Es mangelt einfach an Werbung und die kostet Geld.

So ich denke ich bin jetzt genug abgeschweift ;)
774
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 07. May 2010, 21:12 »
Zitat von: erik
Auch da kann ich Dir nur zustimmen, auch wenn ich persönlich der Meinung bin das selbst ein nicht ganz optimaler Baum immer noch besser als eine lineare Liste ist.
Ich hab mir mal den AVL-Baum etwas näher angesehen und der schein mir recht geeignet und auch nicht zu komplex zu sein. Die B-Bäume machen auf mich keinen so guten Eindruck weil die Nodes ziemlich komplex sind und außerdem der eigentliche Inhalt zwischen den Nodes wechseln kann und noch eine zusätzliche Indirektion finde ich eher ungünstig, die B-Bäume sind wohl wirklich eher für Daten geeignet die lange Zugriffszeiten haben so das die komplexeren Baum-Nodes nicht so ins Gewicht fallen.
Ich bin ein Fan vom AVL-Baum, aber in dem Fall von einer Sleep-Queue muss ich dann auch zugeben, dass ein RB-Baum wahrscheinlich die bessere Wahl wäre. Denn in dem ist das Löschen schneller.

Zitat von: erik
Was meinst Du den dann mit Präzision? Die Laufzeit eines sleep(0815) dürfte kaum auf die Micro-Sekunde genau interessieren, schließlich sagt ja auch der Standard das ein sleep länger dauern darf. Für ein präzises nsleep() sehe ich keinen Bedarf, so alte Hardware wirst Du doch hoffentlich nicht mehr in Deinen PCs haben.
Mit Präzision meine ich z.B. das ein Thread alle 40ms ein Bild berechnet und es dann ausgibt. Wenn ich jetzt nen periodischen Timer von 15ms habe, dann kann der Fehler zw 5ms und 20ms liegen, was ich schon arg ungenau finde. Ich sag mal der Grund ist doch erstmal egal wozu ich die Präzision brauche, das kann ich auch gar nicht wissen, aber ich hätte sie gerne. Das Prinzip läuft auf eine Diskussion der Art 64KiB RAM sind genug hinaus ;)

Um auf die alte Hardware zurück zu kommen. Du möchtest doch sicher das dein OS so schnell wie möglich startet und dem APIC sollte man schon ne gewisse Zeit geben damit er deine Befehle ausführen kann (konkret meine ich das Starten der APs) und wenn du dann jedes Mal als kleinste mögliche Wartezeit 15ms hast summiert sich das schnell zu einer sehr langen Zeit auf. Ich weiß nicht ob du jetzt genau wissen möchtest wie lange man wo warten sollte, aber wenn du es wissen möchtest, dann gucke ich nach und schreibe es noch!

Zitat von: erik
Wenn Du einen Timer mit absoluten Ablaufzeitpunkt als relative Zeit in den Local-APIC-Timer eintragen willst dann benötigst Du eine Bezugszeit, also die aktuelle Ist-Zeit, möglichst in der selben Präzision. Was machst Du in der Situation wenn Du einen Timer mit 60ms hast und gleichzeitig ein neuer Thread laufen soll, dann wirst Du bestimmt erstmal die Zeitscheibenlänge (55,4ms) in den Local-APIC-Timer eintragen, wenn dann der Thread die Zeitscheibe nach etwa 20ms abgeben möchte (was ja nun wirklich nicht unwahrscheinlich ist) dann hat der Timer nur noch 40 ms übrig, trägst Du dann diesen in den Local-APIC-Timer ein und startest einen anderen Thread? Wenn ja, was ist wenn dieser Thread auch vorzeitig seine Zeitscheibe abgibt? Wie bestimmst Du dann wie viel Zeit er von seiner Zeitscheibe aufgebraucht hat, schließlich wurde ja nicht die Zeitscheibenlänge in den Local-APIC-Timer reingeladen? Dieses vermischen unterschiedlicher Dinge erscheint mir irgendwie ungeschickt.
Dein Bsp. ist erstmal ungeeignet, da der Thread ja erstmal in die Queue des PIT gehen würde, da er >55,4ms schlafen möchte.
Ich speichere wie gesagt immer die Zeit ab die ich in den APIC geschrieben habe und jedes Mal wenn der Scheduler aufgerufen wird (ob die Zeitscheibe nun aufgebraucht wurde oder der Thread abgegeben hat) berechne ich die Differenz zwischen der Zeit die ich eingetragen habe und der Zeit die noch übrig ist (kannst du ganz einfach machen, in dem du den Counter ausliest und mit der Zeit eines Ticks multiplizierst). Diese nutze ich dann zum rechnen.
Der Sinn hinter einem One-Shot-Timer ist, dass dieser nur feuert, wenn die Zeit die eingetragen wurde abgelaufen ist. Also ja ich trage genau die Zeit in den APIC ein die ein Thread laufen darf (oder halt die Zeit bis zu dem nächsten Thread der aufgeweckt werden muss, je nach dem was "kleiner" ist).

Praktisch sowas:
timeNextThread= currThread->prio * NETTE_KONSTANTE;
sleepNext= sleepQueue->sleepTime;

if(sleepNext < timeNextThread)
 timeSet= apicSetTimeSlice(sleepNext);
else
 timeSet= apicSetTimeSlice(timeNextThread);

Zitat von: erik
Kann der RTC periodische IRQs generieren?
Außerdem verstehe ich noch nicht wie du einen absoluten Timer und einen relativen Timer synchron halten willst. Ich denke dass das ziemlich Arbeit werden könnte. Also ich würde das nicht freiwillig versuchen.
Also ja die RTC hat nen periodischen Modus aber immer nur 2er Potenzen als Frequenz.
Der Trick ist, dass ich die beiden Timer nicht synchron halten muss! Ich arbeite doch nur bei dem periodischen Timer mit absoluten Zeit und bei dem One-Shot-Timer arbeite ich mit relativen Zeiten.
Bei relativen Zeiten kann es mir doch egal sein, wie der Timer "aus dem Ruder läuft". Ich nutze dort keine Counter um die absolute Zeit zu verfolgen, sondern mich interessiert es nur, ab einem gewissen Zeitpunkt bis zu einem gewissen Zeitpunkt die Zeit so genau wie möglich zu erfassen und wenn der Timer in der Zeit 1ms ungenau ist, naund! Immernoch besser als was ich mit einem periodischen Timer erreichen kann.

Zitat von: erik
Okay, aber Deine Wohnung ist offensichtlich nicht der Normal-Fall. Über die gesamte Erde betrachtet ist x86 definitiv ein Nischenprodukt.
Das habe ich schon verstanden und ist mir bekannt, aber ich dachte wir sind uns schon einig das wir ein OS für einen "normalen" PC schreiben! Denn was interessieren mich DVD-Player oder eingebettete Systeme in Autos oder Mikrowellen oder Hifi-Anlagen? Die PCs an denen wir arbeiten/spielen/gucken sind in der Mehrzahl x86er!
Ich würde mich sehr freuen auch nen potenten ARM-PC zu sehen, aber das ist leider noch nicht der Fall (und bezahlbar sollte er sein). Wenn es darum geht einen PC als User (damit meine ich nen normalen Menschen) zum Internet surfen, Dokumente schreiben, spiele Spielen und Filme gucken zu benutzen, dann sind alle anderen Architekturen Nischenprodukte! Ob das gut und schön ist, sei mal dahin gestellt!
775
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 02. May 2010, 23:22 »
Zitat von: taljeth
Aber wenn es so wäre, wäre ein Baum jedenfalls definitv das falsche Mittel, dann würdest du eine einfache Queue wollen.
Denkfehler meinerseits. Denn dann könntest du ja immer am Ende Anfangen zu suchen und das dürfte in dem Fall wesentlich schneller sein.
776
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 02. May 2010, 22:56 »
Zitat von: erik
Ich denke es hat sich damals gelohnt, ob es sich auch bei einem klassischen General-Purpose-OS lohnt kann ich nicht wirklich beurteilen aber ich vermute das der Baum immer noch zumindest etwas besser als eine lineare Liste ist.
Dazu müsste man mal konkret gucken, was für Zeiten so "geschlafen" werden. Denn wenn du davon ausgehst, das jedes neue Event was in den Baum kommt später endet als das davor, würde sich ein ausbalanzierter Baum schon lohnen.

Zitat von: erik
Die Last, welcher ein 1000Hz IRQ generiert, ist meiner Meinung nach nicht so hoch, sollte auf einer modernen CPU unter 0,1% betragen, und bei SMP trifft das ja auch nur eine CPU. Warum sollte man den PIT bei SMP nicht abschalten können? Wenn Du ihn nicht brauchst, z.B. wenn keine Timer aktiv sind oder der HPET da ist, dann kann man den PIT auch abschalten. Für die Zeitscheiben stehen Dir bei SMP ja garantiert die Local-APICs bereit.
Ich muss doch aber auch an alte Systeme denken, wenn ich schon ne mindest Voraussetzung von nem Pentium habe, dann will ich auch das mein OS da vernünftig läuft und da machen sich 1000 IRQs doch sehr bemerkbar (vorallem wenn ich da an den worst-case mit nem Dual-P75 System denke ;) ).

Zitat von: erik
Aber gerade die wirst Du mit dem PIT-One-Shot-Modus sicher nicht erreichen. Nach 1'080'000 Bildern, bei 60 fps, werden damit bestimmt nicht genau 5 Stunden vergangen sein. Außerdem ist das Beispiel schon vom Konzept her falsch, wenn die GraKa ein neues Bild will dann soll sie doch bitte einen IRQ auslösen.
Da haben wir dann wieder aneinander vorbei geredet ;)

Also wir sprechen jetzt erstmal nur von SMP Systemen und da brauche ich den PIT (oder halt den HPET so weit vorhanden) als globale Zeit! Und da nutze ich ihn ja auch im periodischen Modus, aber halt mit den 18,2Hz. Auf SMP Systemen nutze ich dann den APIC für die Scheduler der CPUs und die laufen im One-Shot Modus, weil da ist der Fehler nicht wichtig, der durch das neu Schreiben des Counter auftritt (zumal er da sowieso minimal sein sollte!). Alle Timer die <55,4ms warten, kommen in die Sleep-Queue einer CPU und dadurch das ich diese dort mit relativen Zeiten reinpacke ist halt auch der Jitter, der sich aufsummieren würde, egal. In der Sleep-Queue vom PIT (oder halt HPET) kommen alle Timer >55,4ms und dort nutze ich dann absolute Zeiten (wegen der von dir schon genannten Vorteile).

Jetzt zu den Single-CPU Systemen. Dort wo ich nur den PIT habe (also keinen APIC, was leider bis zu Athlon XP passieren kann), habe ich mir überlegt die RTC im periodischen Modus zu nutzen (z.B. dachte ich an nen Tick von 62,5ms) und da kommen dann wieder alle Timer mit ner Zeit >62,5ms rein und dort würde ich dann den PIT im One-Shot-Modus nutzen und da ist es dann ja wieder egal wie groß der Jitter, weil er sich nicht aufaddieren kann, da ja nur Timer mit ner Zeit <62,5ms da rein kommen. Ansonsten ist das Prinzip das gleiche.

Zitat von: erik
Nein, der HPET läuft immer, außerdem hat er mehrere Comparatoren und damit mindestens einen Multi-Shot-Mode. Der monoton laufende Counter ist ja gerade der Unterschied zum PIT-One-Shot-Mode. Vom dem Moment an wo der PIT einen IRQ auslöst bis er dann endlich wieder läuft, mit der nächsten Zeitspanne, vergeht immer etwas Zeit, vor allem ist diese Zeit nicht konstant oder vorhersehbar. Für wirklich präzise Dinge (ich meine damit Langzeitgenauigkeit) ist der PIT-One-Shot-Mode nicht geeignet.
Was du mit den Comparatoren meinst ist im Endeffekt nen One-Shot-Modus. Der IRQ wird nur gefeuert wenn das Event erreicht ist und es liegt nicht unbedingt immer die selbe Zeit zwischen den IRQs, es werden also keine sinnlosen IRQs gefeuert, wo du nur nen Counter inkrementierst und sonst nichts machts, weil kein Event gefeuert werden muss.

Zitat von: erik
Also wenn ich Abends ins Bett gehe, schlafe und Morgens wieder aufwache dann ist die Zeit doch auch nicht stehen geblieben. Leider! Wink Die Messung der absoluten Laufzeit Deines Systems darf nicht von irgend einer CPU abhängen.
Auch hier wieder hast du mich wahrscheinlich falsch verstanden. Das Problem auf SMP Systemen ist, das du nicht auf jeder CPU nen Counter haben kannst (auf meinem sowieso nicht, zwecks One-Shot und meinem speziellen idle System) und dann sagen kannst du nutzt den Counter jeder CPU als globale Zeit. Wenn ich von globaler Zeit rede meine ich die absolute Zeit die in der Realität vergangen ist, aber die Counter der CPUs driften irgendwann auseinander, genauso wie die TSCs. Deswegen brauche ich halt auf nem SMP System ne globale Zeit (in dem Fall über den PIT).

Zitat von: erik
Ich wette Du hast in Deiner unmittelbaren Umgebung mehr ARM und MIPS CPUs als x86. Denke mal an DVD-Player, Handy, Drucker und all die anderen elektronischen Spielzeuge in unserem Alltag. x86 ist das tatsächliche Nischenprodukt!
Da muss ich dich in meinem Fall wohl leider enttäuschen (zumindest wenn wir von meiner Wohnung reden ;) ). Denn da können andere CPUs nicht mit meiner Sammlung an Boards und CPUs mithalten ;) Und andere Sachen habe ich nicht großartig (nicht mal nen DVD-Player ;) ).

Zitat von: taljeth
Ich kann im Moment auch nicht richtig abschätzen, wie viele Knoten durchschnittlich im Baum sein werden (wahrscheinlich hätte ich eure Posts dazu mehr als nur überfliegen müssen Wink) - aber ich vermute entweder n ist groß genug, dass zwischen n/2 und log(n) ein nennenswerter Unterschied ist, oder es sind so wenige Knoten, dass eine Liste auch nicht wesentlich langsamer wäre.
Das ist ja im Endeffekt genau das Problem! Wie willst du das vorher wissen? Das geht nicht auf nem OS wo Programme laufen können, die nicht nur du geschrieben hast. Du kannst ja nicht wissen auf was für nette Ideen die Leute so kommen und dann hast du mit einmal ne Queue die 1000 und mehr Einträge hat und da würde sich dann nen ausbalanzierter Baum besser machen (ich seh ein meine Delta-Queue ist da mist ;) )!
777
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 29. April 2010, 23:40 »
Zitat von: erik
Sicher? Das kann ich mir momentan kaum vorstellen. Außerdem bleibt der Overhead das Du die relativen Zeiten immer mitrechnen musst, also zusätzliche Schreibzugriffe erzeugst.
Nope, funktioniert nicht! War ein ganz großer Denkfehler von mir. Denn ich habe vorausgesetzt das ich die Abstände schon kenne, dann würde das klappen aber so nicht :(

Zitat von: erik
Wieso? Ich muss Doch meinen Timer nicht suchen (und wenn wir beide suchen müssten dann wäre der Baum wieder im Vorteil). Ich muss zwar einen Pointer mehr prüfen (um zu wissen welches der beiden Kinder noch da ist, was bei einem abgelaufenen Timer eigentlich klar ist da es keine Kinder mit früherem Ablaufzeitpunkt geben kann) als in einer bidirektional verketteten Liste aber das war es auch schon.
Ich weiß ja nicht von was für nem Baum wir hier sprechen, aber AVL und RB müssen beim Löschen ja wieder "repariert" werden und das ist auf jeden Fall aufwendiger als bei einer Queue.

Zitat von: erik
Das Element das als nächstes Abläuft muss ich nicht suchen sondern ich hab immer einen extra Pointer da drauf.
Das ist clever! Da wäre ich jetzt gar nicht so schnell drauf gekommen, aber ich hätte mir auch überlegt wie ich immer die "kleinste" Node irgendwo speichern kann.

Zitat von: erik
Das stimmt. Ich schreibe es nur ungerne (Du bist bestimmt schon genervt) aber ließ Dir noch mal die PIT-Variante in meinem Ursprungsport durch. Die Löst dieses Problem perfekt (egal wie viele CPUs). Das mit der hohen IRQ-Frequenz sehe ich nicht als so ernstes Problem, machen viele andere OSe ja auch so, jede Sache hat eben ihren Preis. Der einzigste echte Nachteil ist das damit die CPU nicht richtig tief schlafen kann um Energie zu sparen.
Also erstmal du nervst nicht, ich kann sonst solche Diskussionen nicht auf so einem Niveau und über so ein Thema führen!
Gegen den PIT Timer mit einer solch hohen Frequenz habe ich grundsätzlich was! Davon wirst du mich nicht abrücken können. Und das Linux die Frequenz ihres Schedulers wieder geändert (also wieder kleiner gemacht) haben sagt mir das ich nicht so falsch liegen kann ;)
Der Punkt welcher mih stört ist halt, ich kann den PIT auf einem SMP System nicht abschalten, egal welche Frequenz er hat und da möchte ich dann auch soviel es geht "sparen" (also im Endeffekt an Energie und CPU Zeit). Wenn der PC die meinste Zeit am nichts Tun ist, dann kostet das nur unnötig Energie und auch für diesen Fall muss geplant werden (sollte sich eventuell auf einem Laptop sehr sehr negativ auswirken!).

Zitat von: erik
Also ich sehe da keine Vorteile. Vielleicht erklärst Du mir diese mal.
Präzision! Wie ich gerade in einem anderem Forum gelesen habe, macht sich da jemand gerade nen Kopf wie er die Schleife eines Games so umsetzen kann, das er auf max 60FPS kommt und somit die CPU nicht immer zu 100% auslastet. In diesem Zusammenhang meinte einer nimm einfach sleep(1) und dann ist noch rausgekommen, das sleep mindestens 15ms dauert (was ja logisch ist, da Windows nen periodischen Timer nutzt und ein Tick sind 15ms).
Und hier sage ich mir 15ms, das ist ne verdammt lange Zeit! Ich meine es gibt bestimmt genug Treiber die würden gerne wesentlich weniger warten (vielleicht irgendwo im µs Bereich) und bevor die busy-waiting machen, habe ich doch lieber eine Möglichkeit das ein Thread eine so kurze Zeit schlafen kann und in der Zeit kann die CPU schön andere Sachen machen. Das funktionier nun mal am besten mit nem One-Shot-Timer (zumal dein geliebter HPET eigentlich nur diesen Modus implementieren würde, aber aus legacy Gründen noch nen periodischen Modus hat, aber der ist optional)!
Jedes Mal wenn du weniger als 15ms (bei 400MHz sind das 6.000.000 Takte!) warten willst, müsstest du busy-waiting machen und das ganze noch als Real-Time Thread, damit du ja nicht unterbrochen wirst. Das ist ne absolute Ressourcen Verschwendung.
Desweiteren spare ich durch den One-Shot-Modus noch einige IRQs und das sollte sich ab einer Laufzeit von mehreren Stunden schon lohnen, was da gespart wird!

Zitat von: erik
Darum geht es mir gar nicht primär, sondern um die Modularität des Quell-Codes. Wenn Du das Timing über mehrere Module verteilst wirst Du Dich irgendwann später mal ziemlich ärgern darüber. Stell Dir vor Du tauscht mal den Scheduler gegen einen anderen aus, dann gibt es Teile des Timing-Systems mehrmals (in jedem Scheduler). Wartbarer Code ist IMHO was anderes.
Das sehe ich ein wenig anders. Sieh es als ne Art Interface welches implementiert werden muss und wenn du sowieso den One-Shot-Modus nutzen musst (ist bei meinem Timer-Interface so vorgesehen), dann ist es auch kein Problem und Beinbruch diesen Timing-Code noch mit rein zu nehmen. Denn im Endeffekt bleibt das grobe Gerüst des Schedulers immer gleich:
//berechne die Zeit die wirklich verbraucht wurde
diff= thisCPU->timerStart - timerGetCountNSecs();
//ziehe die Zeit von der Zeit ab, die der Thread hätte laufen dürfen
thisCPU->currThread->time-= diff;
//gucke ob ein Thread in der Sleep-Queue ist
if(sleepQueue) {
 //aktualisiere die Zeit des 1. Elements
 sleepQueue->sleepTime-= diff;
 //solange wie die Zeit die der Thread schlafen wollte kleiner ist als eine Konstante, weck ihn auf
 while(sleepQueue->sleepTime <= TIME_KONSTANTE) {
  //hole dir einen Pointer auf den Head der Queue
  struct thread_t *t= sleepQueue;
  //Head entfernen
  sleepQueue= queueRemoveHead(sleepQueue);
  //Thread aufwecken
  threadWakeup(t);
 }
 //hole dir die Zeit wann der nächste Thread aufgeweckt werden soll
 if(sleepQueue)
  sleepTimeNext= sleepQueue->sleepTime;
}
//hier würde jetzt der eigentliche Scheduler kommen, also berechnen welcher Thread als nächstes dran ist oder ob der gleiche Thread nochmal laufen darf usw.
//jetzt stellen wir den Timer ein
if(sleepQueue && sleepTimeNext < thisCPU->currThread->time)
 timerSetTimeSlice(sleeptime);
else
 timerSetTimeSlice(thisCPU->currThread->time);
Wenn ich sowas voraussetze, dann gibt es auch keine Probleme was die Wartbarkeit betrifft. Wenn ich es mir noch "einfacher" machen wollte, dann könnte ich den Scheduler noch weiter "auslagern" indem ich sage, dieses Grobkonzept ruft erst den eigentlichen Scheduler auf! So kann ich dann auch den Code vom Scheduler Code fernhalten!

Zitat von: erik
Wenn bei Dir jede CPU ne eigene Zeit hat dann machst Du IMHO was falsch. Bei mir wird es nur eine Zeit geben, die eine reicht mir einfach.
Damit meine ich eigentlich solche Konzepte, das jeder Core extra runtergetaktet werden kann und schlafen kann, obwohl ein andere Core weiter fleißig rechnet. In dem Moment bleibt für mich auf dem Core die Zeit "stehen".

Zitat von: erik
Genau: Wofür? Ich glaube nicht das normale Programme was genaueres als ein paar Mikrosekunden brauchen. Fürs meiste dürften auch Millisekunden völlig reichen. Programme die wirklich was genaueres brauchen (dazu gehören bestimmt keine Multimediaprogramme o.ä.) machen das sicherlich über ne extra Library welche Du dann auf Dein OS portieren musst, da braucht diese Library bestimmt eh ein paar spezielle SYSCALLs oder die Library bekommt einen eigenen Timing-Treiber mit HW-Zugriff.
Wieso nicht gleich zur Verfügung stellen? Wie gesagt, kann ich mir durchaus vorstellen, das einige Treiber doch ne ganz schön hohe Auflösung bei nem Timer bräuchten.
Um nochmal auf die Multimediaanwendungen zurück zu kommen und auf dein Bsp. das man es nicht merkt wenn der Film zu schnell läuft.
Also da muss ich dir ganz doll wiedersprechen. Ich habe im Moment nur unter Windows 7 sowas von Probleme mit HD Filmen, das ist nicht mehr schön und nur unter Windows 7 unter XP hatte ich die nicht. Ich merke es ganz doll wenn der Film zu schnell läuft. In diesem speziellen Fall haut irgendwas mit der Synchronisation nicht hin, denn nicht mal der Ton läuft fehlerfrei und das beste daran ist, es scheint nicht mal unbedingt ein Treiberprobelm zu sein, denn ich bekomme mit jedem Programm (WMP, VLC, MPC) andere Ergebnisse und der WMP läuft da noch am besten.
Auf meinem Desktop Rechner ist es so schlimm das ich nicht mal ne DVD vernünftig gucken kann :(

So aber wieder back-to-topic.

Zitat von: erik
Darf ich Dich daran erinnern das es noch viele andere Plattformen gibt außer x86? Die meisten dürften deutlich besser sein als x86.
Ich weiß, leider. Denn erstmal sind mir diese zu teuer (ich wäre an ARM und PowerPC interessiert). Dann ist die Situation auf der ARM Plattform nicht wirklich besser. Denn da müsste ich ja für jedes Board bzw. jedes SoC meinen Kernel anpassen, das wäre für mich schon fast wie ne neue Architektur, dann kommen noch die verschiedenen BEfehlssätze dazu.
Was aber alle Argumente schlägt ist einfach die Verbreitung. Warum sollte ich mich mit einer Architektur befassen, die ich in meinem Umfeld gar nicht zu Gesicht bekomme?
Einen Punkt für ARM gibt es aber noch, ich hoffe auf immer mehr Handys mit Android oder nem anderen Linux, so dass man vielleicht irgendwann mal sein eigenen OS auf nem Handy laufen lassen kann. Daran wäre ich wirklich sehr interessiert!
778
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 27. April 2010, 23:30 »
Zitat von: erik
Wenn Du auf dem vordersten Element rumrechnest dann kommt auch immer ein Speicherschreibzugriff zusätzlich, gegenüber einem Vergleich, dazu. Zum prüfen, im IRQ-Handler, ob das vorderste Element nun dran ist müssen wir beide auch nur das vorderste Element anfassen (Du lesen und schreiben, ich nur lesen), das komplette durchgehen der Liste ist dafür nicht erforderlich (siehe meinen IRQ-Handler-Code). Zum beliebigen Einfügen eines neuen Elements musst Du Deine Delta-Queue in jedem Fall linear von vorne an durchlaufen bis die richtige Stelle gefunden ist, ich dagegen kann diese Liste als Baum realisieren und kann daher sehr viel schneller Einfügen. Das Entfernen des vordersten Elementes, also das Element unten links in meinem Baum, ist nur minimal komplizierter als bei Deiner Delta-Queue.
Also ich wüde wahrscheinlich sogar ne Delta-Queue in einen Baum packen können ;)
Was das Entfernen betrifft, ist meine Queue klar schneller, besonders wenn der Baum immer voller wird. Denn du versaust dir da den Cache, durch die "vielen" (ein paar reichen ja) Speicherzugriffe und die "längere" (sollte eigentlich unwesentlich sein) addiert sich ja auch, wenn du doch mal einige Elemente Entfernen musst. Rein theoretisch betrachtet ist die Queue in dem Fall O(1) und der Baum O(log n).

Zitat von: erik
... Mit diesem System bin ich auf einem K6-500MHz auf knapp 600'000 Thread-Wechsel pro Sekunde gekommen, die ungefähr 20 Threads haben auch was sinnvolles getan.
Die Zahl erschein mir irgendwie arg hoch. Denn das macht gerade mal 833 Takte pro Thread und so ein Thread-Wechsel kostet ja doch einiges an Zeit und Performance (oder liefen die alle in einem Adressraum?).

Zitat von: erik
Deinen Code hab ich ehrlich gesagt gar nicht verstanden, Bitte poste ihn noch mal mit reichlich und aussagekräftigen Kommentaren dabei. Was mich stört ist das Du da das einzufügende Element ständig modifizierst und auch das Queue-Element vor (wirklich davor? oder habe ich mich da verschaut? ) welches das neue kommt wird auch modifiziert. In meiner Variante wird nur die richtige Stelle gesucht (nur Vergleiche keine Modifikationen) und dann eingefügt (simple Pointer-Magie, so wie bei Dir), egal ob lineare sortierte Liste oder sortierter Baum, schon allein deshalb (keine zusätzlichen/verteilten Schreibzugriffe) sollte meine Variante schneller sein.
Der "Witz" bei einer Delta-Queue ist doch, das du nur die Abstände zwischen den Elementen speicherst und nicht die direkten (absoluten) Werte. Ich weiß gar nicht mehr in welchem Zusammenhang ich das damals gelernt habe, aber kann schon sein, das es was fürs Zeitmanagement war.
Was du ja schon richtig erkannt hast, ist das deine Lösung nur ein (oder mehrere) Pointer ändern und meiner bis zu 2 Werte und ein paar Pointer, den einen Wert dafür ständig (im worst-case).
Um deine eine Frage zu beantworten, du musst den Abstand zwischen dem einzufügendem Element und dem Element danach ändern, den der Abstand zw. den beiden ist ja anders.
void queueAddDelta(struct thread_t *t) {
//head der queue
struct thread_t *ptr= deltaQueue;
//so lange durch gehen, bis kein element mehr kommt oder wir unsere position gefunden haben
while(ptr->next) {
  //wenn der abstand bis zum nächsten element größer ist, als unser abstand zum vorherigen element, dann haben wir unsere position (das schließt gleich den fall ein, das wir der neue head werden)
  if(ptr->sleepTime >= t->sleepTime) {
   //abstand zum nachfolger aktualisieren
   ptr->sleepTime-= t->sleepTime;
   //ptr wird unser nachfolger
   t->next= ptr;
   //unser vorgänger ist der vorgänger von ptr
   t->prev= ptr->prev;
   //ptr´s vorgänger werden wir
   ptr->prev= t;
   //wir müssen noch den fall betrachten das wir der neue head sind oder halt mitten drin
   if(t->prev) {
    t->prev->next= t;
   } else {
    sleepQueue= t;
   }
   //fertsch, wir können endlich raus hier ;)
   return;
  } else {
   //falls wir unsere position noch nicht gefunden haben, dann müssen wir zumindest unsere zeit (den abstand sozusagen) aktualisieren
   t->sleepTime-= ptr->sleepTime;
  }
  //ab zum nächsten eintrag in der liste
  ptr= ptr->next;
}
//dummerweise sind wir das letzte (element ;) )
ptr->next= t;
t->prev= ptr;
t->next= 0;
}

Zitat von: erik
Du meinst im IRQ-Handler?
Jap.

Zitat von: erik
Beim richtigen rechnen kommt eben noch der Speicherschreibzugriff dazu. Da Du einzelne Werte (viel kleiner als eine Cache-Line), quer über den RAM verteilt, modifizierst könnte das schon recht gut bremsen. Auf den Cache kannst Du dabei jedenfalls nicht zählen, der dürfte IMHO eher bremsen weil er versucht komplette Cache-Lines zu lesen und die modifizierten Cache-Lines dann wieder komplett schreiben will (oder sie im Cache liegen bleiben und dort wertvollen Platz kosten).
Wie oben schon geschrieben, solltest du doch durch die "vielen" Zugriffe (bei einem Baum z.b.) auch den Cache trashen, oder? Aber ansonsten hast du recht.

Zitat von: erik
Wenn Du den PIT abschalten möchtest musst Du das in GetTicks() berücksichtigen oder soll dann in Deinem OS die Zeit stehen bleiben? Wenn es Dir aufs Energiesparen ankommt würde ich eher dazu raten die PIT-Frequenz zu reduzieren, alle 100ms die CPU für ein paar Mikrosekunden aufzuwecken dürfte nur wenig Energie kosten. Wenn Du deutlich besseres Power-Management willst (was eh erst auf recht modernen CPUs und Boards geht) dann solltest Du auch den HPET voraussetzen (der braucht zum laufen fast gar nichts an Energie).
Naja, wozu brauche ich denn die Zeit noch, außer um solche Events auszuführen? Denn für die Uhr wollte ich eigentlich (also mache ich schon) die RTC nehmen, die wird einfach jede Sekunde einmal aktualisiert. Aber gerade fällt mir ein, das einige Dateisysteme die Zeit bis auf die ms genau wollen, oder?

Zitat von: erik
Der TSC ist nur zum Messen von kleinen Zeiträumen gedacht, für präzise Langzeitmessungen gibt es ja den HPET oder die RTC.
Naja, die RTC ist nicht wirklich gut für sowas geeignet (meine bescheidene Meinung) und du immer mit deinem HPET ;) Ich weiß auch das ein Auto besser ist um nach Hause zu fahren (und meistens weniger stressig), aber ich kann mir einfach keins leisten, also fahre ich Zug und mache das beste daraus ;)

Zitat von: erik
Ganz simpel finde ich das nicht. Zum draufaddieren musst Du vorher lesen und das wird in einem Non-Cachable-Bereich eher langsam sein. Wenn Du zum Schluss eh absolute Werte brauchst, warum dann so viel Mühe um immer mit relativen Werten zu arbeiten?
Macht der Gewohneit? Ich weiß es nicht, aber was ich weiß ist, das ich ein riesen Problem habe, auf SMP Systemen (ohne den netten HPET ;) ) ne halbwegs akkurate globale Zeit zu bekommen. Wenn ich das in den Griff bekommen würde, dann kann ich auch absolute Werte nutzen.
So aber finde ich ist es einfacher, zu sagen, so jetzt soll der Thread mal so und so lange schlafen und nicht er soll bis dann schlafen!

Zitat von: erik
Das sieht in meinen Augen irgendwie extrem Aufwendig aus. Ich verstehe nicht welchen Vorteil Du Dir von diesem Aufwand erhoffst. Das ganze kann man doch eigentlich ganz einfach und simpel Lösen.
Ich dachte mir halt, wenn du schon so ein schönes Thema wie die OS Programmierung machst, dann mach es auch richtig und mit richtig meine ich in dem Fall, das ich die höchste Präzision aus den gegebenen Mitteln heraus hole (ohne dabei ander Dinge negativ zu beeinflussen, wie z.B. durch ne PIT Frequenz von 1000Hz).
So weit für SMP Systeme. Für ein CPU Systeme hab ich mich halt vollkommen auf den One-Shot-Modus eingeschossen. Ich find die Idee halt toll und sehe auch die Vorteile, nur leider ist der PIT da anderer Meinung ;) So langsam spiele ich mit dem Gedanken auf PIT only Systemen doch wieder nen periodischen Modus zu nutzen, aber damit nehme ich mir einen Vorteil und das wäre die Präzision von Events. Ich müsste halt abwiegen was schlimmer ist.

Zitat von: erik
Also ich finde es ungeschickt wenn der Scheduler was mit Timing zu tun hat. Ich persönlich bin der Meinung das der Schuler nur für die Verwaltung der Threads (und deren Zustände wie lauffähig, blockiert, schlafend usw.) und für den Kontext-Switch zuständig ist. Ein ordentlicher Scheduler, der mehrere CPUs fair + schnell über die Threads verteilt und dafür effiziente + leistungsfähige Management-Funktionen bietet, ist ansich schon kompliziert genug, da muss man nicht auch noch fremde Aufgaben mit rein packen.
Naja, so wie ich das sehe hat er schon was mit Timing zu tun, denn er kümmert sich doch ohnehin darum wie lange ein Thread laufen darf! Da kann er dann auch noch Events mit einbeziehen, so dass der Thread dann halt ein wenig früher unterbrochen wird. Wirklich komplizierter wird er meiner Meinung nach deswegen nicht.
Das ist übrigenz auch ein wunderbarer Fall für relative Zeiten. Denn wenn du möglichst Präzise (was mit dem APIC auf SMP Systemen ja möglich ist) Events auslösen willst, kannst du dich nicht auf die globale Zeit verlosen, da zu ungenau und da jede CPU ihre eigene "Zeit" hat, musst du halt mir relativen Zeiten arbeiten. Um es mal so zu sagen, kann ich einfach dein Konzeot mit meinem vermischen.
Ich nutze für den PIT die globale Zeit und wecke den Thread nicht auf wenn er gleich der globalen Zeit ist, sondern ich packe ihn in die Sleep-Queue der CPU wenn er kleiner der globalen Zeit+ein Tick ist. Dann kann ich auch andere Datenstrukturen nutzen und habe auch nur noch Vergleiche.
In den Sleep-Queues der CPUs nutze ich dann wieder die Relative Zeit.

Zitat von: erik
Genau deshalb stelle ich mir die Frage: Warum Kompliziert wenn es doch auch so einfach geht? Was erhoffst Du Dir davon? Wo genau siehst Du den Vorteil?
Relative Zeitwerte, mehrere unabhängige Timer und verwische Zuständigkeiten in den SW-Modulen. Klar das kann man alles realisieren aber wenn Du diesen Aufwand treiben möchtest dann erwartest Du doch auch was, ich sehe das nur eben nicht, das müsstest Du mir erklären.
Hatte ich ja oben schon beantwortet. Nur noch mal ganz kurz, höchst mögliche Präzision auf alten (wie neuen) Systemen. Wofür, ich habe keine Ahnung ;)

Sag mir doch mal was das höchste an Präzision ist, was man in einem OS wahrscheinlich brauchen wird. Denn ich versuche ja schon mit meinem System bis auf ns runter zu gehen (beim PIT eher µs).

Zitat von: erik
... Wieso fragst Du das, weil ich wissen möchte wo Du so exotische Boards her hast?
Auch, aber weil du das mit den APICs nicht wusstest.

Zitat von: erik
Meine Erfahrung mit solchen Boards habe ich mit 4x PentiumPro 200MHz 1MB-L2-Cache unter Windows NT gemacht und ich kann Dir sagen das Windows NT verdammt schlecht skaliert hat. Das Board und die CPUs hatten zwar alle APICs aber Windows NT konnte damit nicht allzu viel anfangen. Der IO-APIC war wimre komplett deaktiviert und die Local-APICs wurden von Windows NT nur mit dem absolut notwendigsten (für SMP) benutzt.
Also so richtig kann ich es nicht glauben das der IO-APIC deaktiviert war. Denn das hieße ja, dass alle IRQs immer auf die selbe CPU geleitet wurden (man kann den PIC durchaus auf SMP Systemen nutzen, aber eher sehr unvorteilhaft)! Die APICs sind ja auch für SMP zwingend erforderlich!

Das mit den deaktivierten APICs ärgert mich bis heute, ich meine Athlon XP Systeme sehe ich schon als halbwegs modern an! Und wer kauft sich schon nur ein neues Board damit er sein eigenes kleines OS darauf testen kann ;)

Zitat von: erik
Ja, gerne. Was haste denn für Prozies drauf? Falls Du das Board nicht in Betrieb bekommst würde ich mich dafür interessieren.
Im Moment sind da gar keine drauf. Mir mangelt es an dem richtigen Netzteil, weil wie gesagt eine Art erweiterter AT Standard (P8 und P9 Stecker wie normal, aber zusätzlich noch nen P10 Stecker). Das Board wurde augenscheinlich auch von irgendeinem Vorbesitzer modifiziert (ich glaube um Sockel 7 CPUs laufen zu lassen, aber da irre ich mich wahrscheinlich). Wenn ich es schaffe, dann mache ich mal ein Bild.

Zitat von: erik
Aber man kann den Triathlon bei normalem Wetter (leicht Bewölkt, kein Regen und kein Wind) in normaler Umgebung (Flachland) durchziehen oder, wenn man masochistisch veranlagt ist, bei extremsten Wetter (>100 l Regen pro m² und h mit Windstärke 8 ) und in unpassenster Umgebung (Gebirge). Wink
SCNR
Wer sich gerne quählt ;) Du bist da mit deiner eigenen CPU (bzw. System) ja auch nicht weit entfernt von ;)
779
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 26. April 2010, 23:51 »
Zitat von: erik
In Deinem Beispiel modifizierst Du immer die Werte in der Queue, das dauert länger als ein Vergleich. Den Time-Counter wirst Du auf jeden Fall zählen müssen damit Du die Systemlaufzeit u.ä. hast. Das alles fällt natürlich weg wenn der HPET da ist.
Ich wusste zwar auch nicht immer was mit einer Delta-Queue anzufangen, aber so wie ich dein Wissen einschätze, habe ich eigentlich gedacht das du das Prinzip kennst.

Also bei deiner Methode, musst du doch auch den Thread in eine sortierte Queue reinpacken. Also musst du auch dort linear, ein Element nach dem Anderen durchgehen.

Ich geb dir mal folgenden Pseudo-Code:
void queueAddDelta(struct thread_t *t) {
 struct thread_t *ptr= deltaQueue;

 while(ptr->next) {
  if(ptr->sleepTime >= t->sleepTime) {
   ptr->sleepTime-= t->sleepTime;
   t->next= ptr;
   t->prev= ptr->prev;
   ptr->prev= t;
   if(t->prev) {
    t->prev->next= t;
   } else {
    sleepQueue= t;
   }
   return;
  } else {
   t->sleepTime-= ptr->sleepTime;
  }
  ptr= ptr->next;
 }

 ptr->next= t;
 t->prev= ptr;
 t->next= 0;
}
Ich hoffe dieser Code (ist erstmal fehlerfrei ;) ) und du verstehst jetzt mein Prinzip. Ich muss immer nur vom Head einer Queue einen Wert abziehen, ist also genauso effizient wie dein Vergleich. Denn ob ich einen Vergleich mache (was intern auch nur ne Subtraktion ist) oder ob ich etwas abziehen und bei den Flags dann auf 0 prüfe (was unter C leider nicht möglich ist, glaub ich jedenfalls) ist im Endeffekt das selbe!

Im Endeffekt sind unsere Systeme sich schon ähnlich nur das ich den PIT so langsam wie möglich laufen lassen möchte (bzw. ihn sogar ganz deaktivieren, wenn er nicht gebraucht wird). Wenn ich dein Konzept mit den Events nutze, dann würde ich sogar von meinem PerformanceCounter weggehen, aber eigentlich müsste das OS so eine Funktion bereitstellen und dafür war ja auch mal der TSC gedacht, bevor Intel erst hinterher festgestellt hat, das es dumm ist wenn sich die Aktualisierungsrate mit der Frequenz ändert ;)

Zitat von: erik
Das klingt nach viel rechnen. Wie soll man denn da effizient was einfügen (also nicht ans Ende anhängen)? Da muss man doch vor jedem Vergleich erst mal nen Absolutwert berechnen denn man dann mit dem neuen einzufügenden Absolutwert vergleichen kann und vor allem linear durch wandern. Falls ich Dich falsch verstanden hab dann erkläre mir das mal Bitte genauer. Spätestens wenn Du mit dem HPET arbeitest benötigst Du auf jeden Fall die absoluten Zeit-Werte, denn den HPET-Counter kann man nicht (so einfach) beeinflussen. Das ist der Vorteil meiner PIT-Variante, die ist bis auf ein paar winzige Unterschiede im IRQ-Handler mit der HPET-Variante exakt identisch. Die PIT-Variante emuliert quasi den HPET, nur mit gröberer Zeiteinteilung. Nur noch GetTicks() ist unterschiedlich, läuft aber in beiden Varianten auf einen simplen Speicherlesezugriff hinaus der wohl nur recht wenig kosten sollte.
Die Delta-Queue habe ich ja oben schon erläutert. Was ich noch nicht ganz verstehe ist, das du sachen bemängelst die bei deinem System doch genauso sind. Du hättest nur den Vorteil, das du mit absoluten Werten ne andere Struktur als ne Liste (z.B. nen RB-Tree) nehmen könntest, aber auch du musst sortiert eintragen (was in einer Liste nun mal linear ist) oder du müsstest bei jedem IRQ Aufruf die komplette Liste durch gehen, was alles andere als optimal ist.

Was das Beeinflussen des HPET-Counters betrifft. Wenn ich das alles richtig Verstanden habe, dann gibt man nun nen Comperator (einen Wert, in dem Fall nen absoluten) an und der HPET feuert dann nen IRQ wenn der Counter diesen Wert erreicht hat.
Ich würde das wieder über ne Delta-Queue lösen, einfach auf den alten Wert der schon drin steht den neuen Wert vom 1. Element der Delta-Queue drauf addieren und fertig. Ganz simpel :D

Zitat von: erik
Ich will damit sagen das Du mit dem häufigen Auslesen des PIT-Zählers trotzdem keine genaueren IRQs bekommst, Du also trotzdem auf dem 55ms-Raster hängen bleibst.
Dann hast du leider mein Konzept immernoch nicht verstanden :(

Ich lese den Counter aus um zu wissen wieviel Zeit seit dem letzten PIT IRQ schon wieder vergangen ist, damit ich diese auf die Zeit, die der Thread schlafen will drauf rechnen kann. Denn der IRQ Handler vom PIT zieht immer 55,4ms ab, egal wann der Thread schlafen gelegt wurde. So sichere ich das der Thread mind. genauso lange schläft wie er das vor hat.

Um zu sichern, das ein Thread auch genauer als das 55ms Raster schlafen kann, habe ich ja eine per CPU Sleep-Queue die für alles <55ms zuständig ist und da ich da wieder mit ner Delta-Queue arbeite, ist auch mein Jitter nicht so schlimm. Denn der kann sich ja nicht immer wieder aufsummieren (jedenfalls nicht was die Sleep-Queue betrifft).

Zitat von: erik
Das macht irgendwie einen komplizierten Eindruck. Vielleicht täuscht mich das, aber wenn der Scheduler das Timer-Management berücksichtigen muss dann finde ich persönlich das irgendwie ungeschickt. Außerdem scheinst Du Dich auf verschiedene HW-Timer zu verlassen, die werden 100%-tig auseinander driften, das gibt sicher viel Freude.
Wie gesagt, da der Scheduler-Timer nur für alles <55ms zuständig ist, kann eigentlich nicht viel passieren. Gerade da ein Thread mit normaler Prio bei mir 30ms als Zeitscheibe bekommt, wird der Scheduler im average-case 2mal aufgerufen und der Jitter ist dort selbst mit PIT "gerade" mal (3*832ns für lesen beim reinpacken des Threads + 5*832ns pro Scheduleraufruf= 13*832ns=) 10816ns= 10,8µs, was ich für verdammt gut für so ne alte Krücke halte ;) Wenn du jetzt noch den APIC-Timer für den Scheduler nimmst, dann wird es noch genauer!

Das einzige Problem was ich haben werde, sind halt PCs die nur nen PIT haben, da summiert sich dann der Jitter auf, obwohl ich gerade ganz spontan mit dem Gedanken spiele in dem Fall die RTC dafür zu mißbrauchen ;) Also das ich die RTC für´s Grobe nutze und den PIT für´s "feine", dann summiert sich mein Jitter auch nicht auf. Muss ich mal sehen ob ich das irgendwie vernünftig über mein Interface umsetzen kann.

Zitat von: erik
Ich persönlich bin der Meinung das eine zusätzliche Ebene (schlafen legen und aufwecken musst Du den Thread ja trotzdem) auch zusätzliche Zeit kostet.
Ja, aber nur wenn das Event noch nicht ausgelöst wurde. Was willst du denn dann machen oder besser gesagt, wie willst du dann warten. Du musst doch den Thread auch schlafen legen (ich hätte vielleicht sagen sollen, das er so lange wartet bis er aufgeweckt wird und nicht eine bestimmte Zeit schläft).

Zitat von: erik
Klingt nach aktivem warten, sowas sollte man nur für wirklich kurze Zeiten machen, und das mit dem ausrechnen der sleep-Zeit ist IMHO genauso ungeschickt (was macht man da mit negativen Ergebnissen).
Ich hab von Spieleprogrammierung keine Ahnung, obwohl mich ne 3D-Engine auch reizen würde :D
Ist halt das einzige was ich kenne wo dieser PerformanceCounter verwendet wurde, aber da du mich ja inzwischen von deinem Event-System überzeugt hast, kann ich das ja erstmal vergessen ;)

Zitat von: erik
Wo hast Du denn z.B. das Board mit mehreren Sockel 5 her? Im normalen Handel gab es das bestimmt nicht. Laut http://de.wikipedia.org/wiki/Sockel_5  ist in den Sockel 5 CPUs immer ein Local-APIC drin, bei allen neueren CPUs sowieso.
Da muss ich dich dann mal ganz frech nach deinem Alter fragen und wie lange du dich schon mit der OS Programmierung auf x86 beschäftigst ;)

Denn den APIC haben die alle drin, der wird aber immer deaktiviert, Ausnahmen sind halt Dual-Sockel-Boards. Selbst bei nem Athlon XP wurde das noch meistens gemacht. Das war ein Grund warum ich mir mal nen neues Board geholt habe, weil EPOX damals gesagt hat, es bringt nur Probleme und deswegen lassen sie den APIC deaktiviert.
Aber das beste war die Begründung, der IO-APIC macht nur Probleme, da frag ich mich dann wieso der APIC nicht genutzt werden kann ohne das ein IO-APIC da ist!?

Wenn du willst mache ich dir nen Foto von dem einen Sockel5 Board was ich hier habe? Bei dem hast du sogar recht, das muss irgendeins aus nem Server sein. Denn ich habe bis heute kein Netzteil dafür :( und weiß erst seit dem Wochenende dass das mal nen kleiner Standard war (nen erweiterter AT).
Ein anderes ist noch bei meinen Eltern zu Hause (da ist mein großes Lager ;) ). Das verwendet sogar die defaul Konfiguration der MPS. Sockel 7 habe ich dann auch nochmal 2 und 1 Sockel 8 Board habe ich doch total unterschlagen ;) (alles natürlich Dual-Sockel).

Zitat von: erik
Aber wenn Du so auf "rumquählen" stehst dann kann ich Dir versichern das Deine Wahl für x86 genau richtig war und sicher noch für lange Zeit bleiben wird. Wink
Darauf würde ich dir mit nem anderen Hobby von mir antworten. Andere sehen Triathlon auch nur als Quählerei an, ich sehe sowas was Herausforderung und wenn man es geschafft hat, dann kann man auch Stolz auch sich sein. Was soll ich mir denn leichte Ziele setzen?! Dann reicht es ja das neueste Spiel durch zu zocken, aber das macht nicht halb so viel Spaß, man lernt nicht so viel dabei (von der Erfahrung mal ganz abgesehen) und es gibt verdammt viele die aus auch schaffen.
Um es mal so zu sagen, OS Programmierung ist doch ne Extreme Sportart unter den Programmierern ;)
780
Lowlevel-Coding / Re: Konzept für periodische Events
« am: 25. April 2010, 23:24 »
Zitat von: erik
Wenn Du viele Threads am schlafen hast dann wird das schnell zu einem Problem. Ich würde lieber die absolute Zeit des Aufweckens errechnen (dafür muss man natürlich den Zeit-Counter lesen, was beim HPET ein HW-Zugriff ist) und diesen in eine sortierte Liste eintragen. Der IRQ-Handler für den periodischen PIT-IRQ inkrementiert seinen SW-Zahler und vergleicht dann diesen absoluten Ist-Zeit-Wert mit dem absoluten Soll-Zeit-Wert im vordersten Listeneintrag. Bei Gleichheit wird eine entsprechende Aktion ausgelöst. Das kann das simple Aufwecken eines Threads sein (der einfach nur ein sleep() gemacht hat) aber auch das verschicken einer Message/Signals an einen Prozess oder das setzen eines Event-Object auf das möglicherweise gerade jemand wartet der dann sofort geweckt werden muss.
Irgendwie habe ich das Gefühl das wir aneinander vorbei reden ;)

Wo ist jetzt der Unterschied ob du die Threads aufweckst, wenn ihre Zeit abgelaufen ist oder du sie in eine neue Queue packst?
Genauso verstehe ich nicht wo der Unterschied ist ob ich ne Zahl hab und den Thread aufwecke wenn diese Zahl bei "0" ist oder ob zwei Zahlen habe und den Thread aufwecke wenn beide gleich sind?!

Auch sollte ich vielleicht näher erläutern was ich mit einer Delta-Queue meine, denn das ist ne sortierte Liste!

Also in einer Delta-Queue stehen nicht die Absoluten Werte, sondern immer der Abstand zum Vorgänger, so dass nur im 1. Element der Liste der Absolute Wert steht.

Zitat von: erik
Du möchtest quasi den Zählerwert vom PIT als Nachkommastellen für Deinen 18,2Hz-Software-Zähler nutzen? Interessante Idee aber ich glaube nicht das das viel nutzt genauer als auf ca. 55ms bekommst Du damit trotzdem keinen IRQ. Ich würde lieber zu einer höheren IRQ-Frequenz raten.
Auch hier kann ich dir nicht folgen :(

Also folgender Pseudo-Code:
void sleep(uint64t time) {
 //Pointer auf aktuellen Thread holen
 struct thread_t *thread= threadGetCurrThread();
 //die Zeit die geschlafen werden soll + die schon seit dem letzten Tick vergangen ist speichern
 thread->sleepTime= time + (timerGetCountNSecsPerTick() - timerGetCurrCountNSecs());
 //Thread in the Sleep-Queue des Timers packen
 timerAddThread(thread)
}
Und der Code des Timer (z.B. der PIT) würde ungefähr so aussehen:
void timerIRQhandler() {
 if(sleepQueue) {
  //Pointer auf das 1. Element der Queue
  struct thread_t *t= sleepQueue;
  //Zeit für einen Tick vom 1. Element abziehen
  thread->sleepTime-= timerGetCountNSecsPerTick();
  //gegebenenfalls Threads aufwecken
  while(t->sleepTime <= timerGetCountNSecsPerTick()) {
   //1. Element der Queue entfernen
   sleepQueue= queueRemoveHead(sleepQueue);
   //1. Element der Queue in die CPU Sleep-Queue packen, da müsste dann auch die Zeit die der Timer der aktuellen CPU schon verbraten haben, nochmal drauf gerechnet werden, so wie oben
   schedAddThreadSleep(t);
   //Pointer aktualisieren
   t= sleepQueue;
  }
 }
}
Und in meinem Scheduler dann ungefähr sowas:
void schedHandler() {
 if(thisCPU->sleepQueue) {
  struct thread_t *t= thisCPU->sleepQueue;
  //Zeit (dauer der gerade abgelaufenen Zeitscheibe) abziehen
  t->sleepTime-= thisCPU->lastTimeSlice;
  while(t->sleepTime <= NE_KONSTANTE_WO_ES_SICH_NICHT_MEHR_LOHNT_DAS_DER_THREAD_NOCHMAL_SCHLAEFT) {
   thisCPU->sleepQueue= queueRemoveHead(thisCPU->sleepQueue);
   schedAddThreadReady(t);
   t= thisCPU->SleepQueue;
  }
 }
}
So ich hoffe ich konnte mich jetzt genauer und besser Ausdrücken ;)

Zitat von: erik
Bist Du sicher das Du Boards mit Slot1 oder Sockel5/7 und mehreren CPUs hast?
Damals aus reiner Sammelleidenschaft und heute zum Testen meines OSs :D Damit ich mich ja auch mit den "schönsten" Seiten der x86 Architektur rumquählen darf ;)

Zitat von: erik
Ja. Solange Du den PIT nicht frei laufen lässt sondern immer mal dran "rumdrehst" bekommst Du Fehler die sich aufakkumulieren.
Naja, das lässt sich nicht wirklich vermeiden, wenn man eh so ne "alte" Krücke hat die nur den PIT und nicht mal den APIC unterstützt ;)

Aber mal was anderes irgendwo habe ich mal gelesen das man, auch wenn der Local-APIC deaktiviert ist, einige Sachen benutzen kann?! Muss ich direkt nochmal nach gucken ob ich dazu nochmal was finde.

Zitat von: erik
Für Spiele oder Multimediaprogramme würde ich ein Event-Object benutzen:
Der Punkt ist, meine Semaphore/Futex Idee wäre aber schneller ;) Weil du nur noch ein "lock sub dword[event],1" machst und wenn das Event gefeuert hat, dann kannst du gleich weiter machen (weil der neue Wert größer 0 ist) und wenn nicht, dann rufst du den Kernel auf und legst dich in der Semaphore "schlafen" und das Event weckt dich dann mit dem Semaphore-Code wieder auf. Also mir gefällt diese Idee :D Aber ich wenn du mir sagst warum dir diese Idee nicht so gefällt kann ich die Nachteile vielleicht auch erkennen. Dazu haben wir den Thread ja!

Zitat von: erik
Wenn Du diese "Performance Counter" nur zu "Statistischen Zwecken", z.B. zur Anzeige in einem Taskmanager, nutzen möchtest dann solltest Du Dir da erstmal keine zu großen Sorgen machen. User-Code sollte sich von so etwas nie abhängig machen.
Ich hab halt mal nen Bsp. für ne innere Schleife bei nem Game unter Windows gesehen und da haben die es so gemacht. Also mit QeueryPerformanceCounter. Da bin ich dann ganz frech davon ausgegangen das man das unter anderen Systemen ähnlich löst. Wenn ich mich recht entsinne, sollst du unter Linux sowas mit der "Zeit" machen, die geben die, glaub ich in ms oder noch genauer an und da sollst du die beiden Werte dann vergleichen, halt was ähnliches nur nicht so genau.
Seiten: 1 ... 37 38 [39] 40 41 ... 43

Einloggen