Autor Thema: Multitasking  (Gelesen 5723 mal)

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« am: 12. November 2004, 17:11 »
Falls ihr in euren OS Multitasking eingebaut haben solltet, wollte ich mal wissen wie ihr das so bewerkstelligt. Verlasst ihr euch da auf die von der Hardware  gegebene Möglichkeit mit TSS oder so?
Ich hab ne  eigene Lösung dazu entwickelt, die ohne TSS auskommt, aber dennoch so ziemlich das selbe bietet, habs sozusagen auf  Softwareebene implementiert. Vielleicht ist meine Möglichkeit ja sogar schneller  als das  Hardwarezeugs, da ich einige Speicherzugriffe weniger habe, da wie ich finde nicht alles  gebraucht wird, was dabei ist. Kann den Code ja mal vorstellen, in der nächsten Ausgabe oder so.  Hab den grössten  Teil davon in GCC Inline asm geschrieben.
Also wie macht ihr so wenn ihrs denn macht^^
Vielleicht kommen ja paar anregende Ideen bei raus^^
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

Bassai

  • Beiträge: 13
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 19. November 2004, 14:03 »
Also ich habe das mal mit den TSS probiert. Diese sind zwar, wie schon erwähnt , insgesamt etwas langsamer als Software Multitasking, aber ich denke, bei den heutigen Rechnern macht das wohl eher nicht so sehr viel an der Performance aus.
Ich dachte, mit den TSS behalte ich nen besseren Überblick, aber es ist warscheinlich Geschmackssache, wie man das macht oder was meint ihr?

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #2 am: 19. November 2004, 16:35 »
Ich finds Sowtwaremässig besser, schneller ist besonders in dem Bereich relativ wichtig, weil nehmen wir an wir haben 100 Davon pro Sekunde(was nicht viel ist) und wir vergleichen das mal dann macht sich das schon bemerkbar, da spart man schon ein paar tausend takte, mit denen man viel machen kann, ausserdem wird beim TSS switch die Anzahl der Tasks durch die maximale Deskriptorzahl begrenzt, beim Softwaremässigen is das absolut variabel.
Der Hauptgrund warum ich das so mache, ist das das TSS bei mir nicht auf Anhieb ging, und wie ich dann so bin denk ich über alternativen nach^^
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #3 am: 20. November 2004, 00:22 »
Hi.

Das mit der Deskriptorbegrenzung ist zwar korrekt, jedoch hast du 8192 verfügbare Deskriptoren....hab noch kein System gesehen was so viele Tasks hat :)

Die Anzahl der Taskswitches ist so einfach auch nicht zu beurteilen.
Es kommt drauf an wie lang ein Task jeweils die CPU nutzen darf. 10 ms sind (wie ich gelesen habe) so das Mittelmaß, was bedeuten würde das in einer Sekunde bis zu 100 Taskswitches erfolgen würden.

Zu beachten sei jedoch dabei, das in einem System Tasks mit hoher Priorität auch mal mehr als 10 ms erhalten. Zudem ist es auch oft so, das viele Tasks idlen...sprich sie warten auf Hardware, oder auf Benutzereingaben.

Da die OS die wir hier schreiben aber weder auf Performance getrimmt werden sollen, noch das sie wohl nie in Komerziellen Anwendung kommen, sollte man sich den Weg überlegen, den man am Einfachsten realisieren kann :)

Auch beim Softwaretaskswitching kann man Performance verlieren wenn der Code unnötig umfangreich ist. Sprich hier bietet es sich in jedem Fall an, die Algorithmen möglichst zu optimieren und wenn gar nicht ganz in ASM zu realisieren.
----------------------
Redakteur bei LowLevel

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #4 am: 20. November 2004, 21:55 »
Naja die Tasksteuerung erfolgt ja bei mir über IRQ0 der wird regelmässig ausgelöst, also weiß ich wie oft der passiert^^ Ausserdem hab ich zwar nen Prioritätensystem für meine Tasks, aber die Handler wird trotzdem jedesmal aufgerufen, das machen alle OS' so, nur wird dann direkt wieder in den Task zurückgeschalten wenn er höhere Priorität hat.
Bei mir ist alles in asm geschrieben, geht auch garnicht anders, zeig mir mal wie man push eax mit C macht^^ oder die Sicherung der Flags oder MMX Register^^ Insgesamt werden nicht mal 100 Instruktionen ausgeführt (glaub ich), darunter kein einziges mul oder ähnliches Taktfressendes Ungetüm. Meinen Algorythmus find ich so wie ich ihn hab super^^ wüsste nicht was sich daran verbessern liesse, werd das mal posten wenn ich wieder an meinem Rechner bin.
Das idlen is normal, kommt ja ständig vor, aber man braucht den Tasks ja nur die Möglichkeit geben von selbst den Taskwechsel zu machen, also im Endeffekt ne Mischung aus Preemtivem und Kooperativem Multitasking, ich habs so^^
Mein OS trimme ich auf Performance^^ wenn dann richtig
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 09. December 2004, 09:01 »
@Roshl
kannste den Code mal posten, ich mache auch Software Taskswitching, daher würde mich deine Variante mal interessieren!

Bei mir siehts so aus:
1. Alles pushen
2. Scheduler aufrufen #new_esp=Scheduler(esp)
3. Alles poppen

Das einzige Problem ist daran, das der Scheduler in der Kernel Umgebung liegt, d.h. cr3 und alle Selektoren müssen korrekt gesetzt sein. Also muss man vor dem Aufruf von Scheduler alles neusetzen. Und ob das so gut (schnell) ist?

MfG GhostCoder
A man, a legend!

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #6 am: 09. December 2004, 15:54 »
ich machs wie ghost! ich pushe alles, dann hole ich den nächsten task, lade den stack, und pope dann wieder alles! aber achtung: @ghostcoder: da musste aufpassen, dass du beim initen eines task zuerst alle register pushst, wie sie am anfang des taskes sein sollen, und dann sp in die tabelle machst, denn sonst will der einen iret und ein popen auf etwas machen, was net aufm stack ist, d.h. er springt zu 0:0 und da gibbet dann nix anständiges mehr... und dann CRASH!
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #7 am: 09. December 2004, 16:38 »
Also ich machs im Prinzip genauso, mein Scheduler läuft auch im Kernelring, macht aber nix, hab den direkt in den Int eingecodet. Wasich da noch einbaun muss wäre die Sicherung der der FloatingPoint  Register, und das mit dem Paging innerhalb des Schedulers müsste auch noch, hab aber so bisher keine Probleme bekommen. Ne kleine Prioriätsverwaltung steckt auch mit drin. Hier mal der  Code:

_Taskhandler:
push eax
push ebx
push ecx
push edx
push edi
push esi
push ebp
push ds
push es
push fs
push gs
pushfd
mov eax,cr3
push eax

mov ax,0x10
mov ds,ax
mov ecx,[_TaskManCurrentTaskID]
mov eax,ecx
shl eax,3
mov bl,[eax+1]
or bl,bl
jz .nexttask
dec bl
mov [eax+1],bl
jmp .execnexttask

.nexttask:
mov [eax+4],esp
mov bx,ss
mov [eax+2],bx
mov bl,[eax]
mov [eax+1],bl

mov edx,[_MaxTaskID]
.seeknexttask:
cmp ecx,edx
jnle .neu
add eax,8
inc ecx
mov bl,[eax]
or bl,bl
jz .seeknexttask

dec bl
mov [eax+1],bl
mov esp,[eax+4]
mov bx,[eax+2]
mov ss,bx
mov [_TaskManCurrentTaskID],ecx
jmp .execnexttask

.neu:
push 1
pop ecx
mov eax,8
jmp .seeknexttask

.execnexttask:
pop eax
mov cr3,eax
popfd
pop gs
pop fs
pop es
pop ds
pop ebp
pop esi
pop edi
pop edx
pop ecx
pop ebx
mov al,0x20
out 0x20,al
pop eax
iret

Die Tabelle für die Tasks liegt bei 0x0.  der erste Eintrag ist ein 0-Eintrag.
Ein Eintrag für die tasktabelle sieht so aus:
db Priorität_general
db Priotität_aktuell ;wird runtergezählt
dw _ss
dd _esp ; für den Stackrahmen des Prozesses

falls was unklar  ist fragt halt
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #8 am: 09. December 2004, 16:41 »
warum benutzt du nicht pusha und popa?
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #9 am: 09. December 2004, 16:57 »
Hab ich dir ja grad im ICQ erklärt, aber noch mal für alle:
Intelprozessoren haben mehrere Ausführungspipelines, so können unter bestimmten Bedingungen mehrere Befehle gleichzeitig ausgeführt werden. Also bestimmte Operationen hintereinander gehen gleichzeitig, diese werden dann pairable Operations genannt, push ist eine die man mit sich selbst pairen kann, also 2 pushs gleichzeitig (auf p2 und  höher auch mehr, da hängts dann von den  uops ab aberdas würde hier zu weit führen) . Bei dem pusha ist das nicht möglich, meistens wird da sogar hinterher ein AGI Stall  auftreten, was auch wieder Takte braucht. Also die einzelnen  pushs sind schneller. Hat einfach mit sehr viel Optimierung zu tun. Ist ein Thema das auf den x86 ganze Bibliotheken füllen kann.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #10 am: 09. December 2004, 19:05 »
Zitat von: Roshl
Hab ich dir ja grad im ICQ erklärt...

vielleicht haben ja andere auch noch die frage gehabt...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 10. December 2004, 13:09 »
Hiho,

erstmal danke für den Code Roshl! Mein Code ist fast genausso, nur das ich einen C Scheduler habe. Aber das Problem (du bist immernoch im Userprozess, musst aber CR3 vom Kernel laden, obwohl man nicht drauf zugreifen kann) ist leider nicht darin vorhanden.

Wenn du willst kann ich meinen Code auch nochmal posten...

MfG GhostCoder
A man, a legend!

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #12 am: 10. December 2004, 15:44 »
Ich seh da kein problem weil:
Der IRQ 0 lädt ja (bei mir) nen Codesegement das Privileg 0 hat, also kanns auf alles zugreifen. Ich seh da zumindest bei mir kein Problem. Weil der  Code nichts mehr mit dem Userprozess zu tun hat.
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 10. December 2004, 20:28 »
Hiho,

das Problem tritt ja erst auf, wenn du Paging an hast. Das du den passenden Codeselektor hast, ist klar, und ds kann man ja auch einfach setzen...

Aber du musst ja, während du noch im Speicherbereich des Prozesses bist, den Wert vom Kernel cr3 (Paging Directory) finden, dann setzen, danach den Scheduler Code ausführen, und dann wieder cr3 des neuen Prozesses setzen.

Eigentlich könnte man gut dafür tss benutzen, sonst kann man noch den OpCode finden, der cr3 setzt, und dann einfach den Parameter setzen, also z.B. suchste nach 0x12345678, wenn du als Dummy im Scheduler


mov eax,0x12345678
mov cr,eax


Was jetzt aber schneller, und effizienter ist, weiß ich noch nicht. Aber wahrscheinlich nehme ich Methode 2...

MfG GhostCoder
A man, a legend!

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #14 am: 12. December 2004, 11:04 »
Ich hab Paging ja an^^
Mein Pagingdirectory liegt an ner festen Stelle also is das kein Problem bei mir, da man ins cr3 ja die lineare adresse schreibt nicht die virtuelle  :wink:
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 12. December 2004, 13:26 »
Hiho,

mein Paging Directory ist ja nicht an einer festen Stelle, daher kamen die Probleme, aber hab das jetzt so gelöst, das ich die OpCodes passend überschreibe, ist ja auch kein Problem... Vielleicht änder ich das mal...

Ja, ist schon klar das das pg-dir an ner linearen Addresse liegt, wäre sonst auch irgendwie "komisch" :)

Aber sonst läuft mein Code ziemlich gut und schnell. Endlich!
MfG GhostCoder
A man, a legend!

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #16 am: 03. January 2005, 09:48 »
mein Multitasking mit eigenem EMS-Paging/Swapping geht jetzt auch...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

 

Einloggen