Aus meiner Sicht würde ich das anders formulieren: Im Average-Case ist Dein System X-fach langsamer als andere weil Du die Daten (mehrfach sogar, falls ich Dich richtig verstanden habe) kopierst und im Best-Case kommst Du immer noch nicht ganz an die Konkurrenz ran (selbst die nicht Zero-Copy-Konkurrenz dürfte kaum einholbar sein).
Wie kommst du darauf das mein System X-fach langsamer sei? Ich meine wir gehen einfach mal davon aus, dass alle Daten in die Pipe passen ohne das der Writer warten muss, das die Daten wieder daraus gelesen werden.
Im normal Fall läuft es doch so ab, du allokierst einen Speicherbereich für deinen Buffer für eine Nachricht, kopierst die erforderlichen Sachen in den Buffer rein und machst einen Syscall das du eine Nachricht versenden willst. Die Nachricht wird dann in einen Buffer im Kernel kopiert (dieser muss auch vorher allokiert werden, was bei dynamic-size Msgs unter Umständen ne "Weile" dauern kann).
Wenn der Empfänger dann die Nachricht abholt gibt es 2 Möglichkeiten, entweder sein Empfangsbuffer ist für die Nachricht groß genug oder er muss erstmal einen Syscall machen um zu wissen wie groß die Nachricht ist. Dann allokiert er einen Buffer und ruft nen Syscall auf, das er die Nachricht haben will. Die Nachricht wird dann aus dem Kernelbuffer in den Buffer des Clienten kopiert.
So ungefähr sollte das auf allen Systemen aussehen die asynchrones IPC zur Verfügung stellen. Die Nachricht muss in einem Buffer im Kernel zwischengespeichert werden und den Speicher, wo der Buffer drin liegt, kannst du dem Sender auch nicht einfach wegnehmen. Genauso ist es normal das du mit dem Speicher wo du die Nachricht hast reinkopieren lassen, machen kannst was du willst.
Ich bin mir ziemlich sicher dass das IPC von Haiku so aussieht, wie die aber das mit fread und solchen Konsorten gelöst haben, weiß ich nicht, müsste ich mal nachgucken. Die nutzen dynamic-size Msgs.
Ich weiß das man beim synchronen IPC versucht das Kopieren zu vermeiden, aber wie will man das mit sehr großen Nachrichten anstellen? Weil die Nachricht müsste ja in den Kernelstack des Senders passen, damit du ihn einfach vom Kernelstack in den Userstack des Empfängers kopieren kannst.
Aha, deswegen ein Haufen extra Syscalls für das Memory-Sharing usw?
Ich verstehe nicht was du mit den extra Syscalls meinst. Weil SharedMem habe ich sowieso (wie jedes andere OS auch haben sollte) und das nutze ich halt dafür.
Was ist bei Dir der "Treiber"? Der Dateisystem-Treiber (z.B. für ext2) oder der Block-Device-Treiber (z.B. für SATA)? Falls ersteres, warum sollte der VFS die Anfragen zerstückeln? Der weiß doch gar nicht das die Datei fragmentiert auf der Platte liegt (der VFS hat noch nicht mal ne Ahnung das man Dateien fragmentieren müsste/könnte). Falls letzteres, wo wird das Dateisystem verwaltet? Doch hoffentlich nicht im VFS, dann könnte man nicht mal einfach so ein NFS o.ä. einbinden.
Also ich gehe im Moment schon davon aus, dass das (z.B.) ext2 Modul dafür verantworlich ist, die einzelnen Blöcke (LBAs) von der Platte (oder woher auch immer) zu laden.
Ich stelle mir das so vor, das du als Modul (z.B. ext2) dem VFS verschiedene Funktionen zur Verfügung stellst (z.B. open, close, read, write, ...) und dich (damit meine ich das Modul) sehr wohl darum kümmerst welche LBAs zu der Datei gehören.
NFS ist ein Netzwerkfilesystem, oder? Sehe ich jetzt spontan kein Problem, anstatt nen Blockdevice Treiber nach den Daten zu fragen, fragt er (NFS-Modul) einfach den Netzwerk-Treiber nach den Daten.
Es kann sein das ich mir das jetzt zu einfach mache, aber das liegt daran, dass ich bei dem Thema null-Ahnung habe.
Okay, ich denke das hab ich verstanden, aber das erscheint mir irgendwie unnötig umständlich.
Aus meiner Sicht ist das schneller/besser als wenn ich sage, das er die Daten per Msg verschickt.
Wer ist "er" und "ihn"? Falls beides der Block-Device-Treiber ist, warum wird der Speicher nicht erst mal vom Dateisystem-Treiber analysiert/ausgelesen?
Der Blockdevice-Treiber. Was meinst du mit deiner letzten Frage?
Ich denke das hab ich ebenfalls verstanden, auch wenn ich das immer noch ziemlich umständlich finde.
Wieso? kommt dem Zero-copy ziemlich nahe, bzw. ist es sogar. Das dürfte so ähnlich wie dein Konzept aussehen.
Hier kommen wir meiner Meinung nach zum Problem in Deinem Konzept. Warum "willst" Du nicht auf das kopieren verzichten?
Problem ist (in meinem Kopf) das Paging, ich will nicht ohne das es der Prozess weiß, in den Pagingtabellen rumfummeln. Denn das müsste ich machen damit ich anstatt seines (der Empfänger/Client) Buffers, meinen eigenen nehmen kann.
Man könnte jetzt streng genommen sogar sagen, dass fread daran Schuld ist. Denn fread sagt das du den Buffer übergibst wo die Daten rein sollen und nicht das du nen Buffer zurück bekommst wo die Daten drin sind.
Sorry, für dieses vernichtende Urteil aber dieses Konzept wirkt auf mich irgendwie extrem umständlich und von der verkehrten Seite angegangen.
Du hast mich erst überzeugt das mein Konzept richtiger Mist ist, wenn ich ein besser (eventuell mit deiner Hilft
) habe. Aber es sollte auch vernünftig für Paging umzusetzen sein.