2009-12-07 5 views
10

Oftmals lese/höre ich das Argument, dass viele Systemaufrufe etc. ineffizient wäre, da die Anwendung einen Modus wechseln, dh vom Benutzermodus zum Kernelmodus und nach der Ausführung wechselt Der Systemaufruf beginnt mit der Ausführung im Benutzermodus, indem erneut ein Moduswechsel durchgeführt wird.Was ist der Overhead in einem Moduswechsel

Meine Frage ist, was ist der Aufwand für einen Modus wechseln? Wird CPU-Cache ungültig oder TLB-Einträge werden gelöscht oder was passiert, wenn Overhead verursacht wird?

Bitte beachten Sie, dass ich über den Aufwand im Modus wechseln und nicht Kontext wechseln frage. Ich weiß, dass Moduswechsel und Kontextwechsel zwei verschiedene Dinge sind, und ich bin mir voll bewusst über Overhead, der mit einem Kontextwechsel verbunden ist, aber was ich nicht verstehe, ist, welcher Overhead durch einen Moduswechsel verursacht wird?

Wenn sein mögliches bitte einige Informationen über eine bestimmte * nix-Plattform wie Linux bieten, FreeBSD, Solaris usw.

Grüße

lali

Antwort

8

Es sollte auf eine keine CPU-Cache oder TLB bündig einfacher Modusschalter.

Ein schneller Test sagt mir, dass auf meinem Linux-Laptop dauert es etwa 0,11 Mikrosekunden für einen Userspace-Prozess einen einfachen Syscall, der eine unbedeutende Menge an Arbeit außer dem Wechsel in den Kernel-Modus und zurück. Ich verwende getuid(), das nur eine einzelne Ganzzahl aus einer In-Memory-Struktur kopiert. strace bestätigt, dass der Systemaufruf MAX-mal wiederholt wird.

#include <unistd.h> 
#define MAX 100000000 
int main() { 
    int ii; 
    for (ii=0; ii<MAX; ii++) getuid(); 
    return 0; 
} 

Dieser Vorgang dauert ca. 11 Sekunden auf meinem Laptop, gemessen time ./testover verwenden, und 11 Sekunden geteilt durch 100 Millionen Sie 0,11 Mikrosekunde gibt.

Technisch gesehen sind das zwei Modusschalter, also könnte man behaupten, dass ein einzelner Modusschalter 0,055 Mikrosekunden braucht, aber ein Einwegschalter ist nicht sehr nützlich, also würde ich die Hin- und Rückzahl berücksichtigen um so relevanter zu sein.

1

Es gibt viele Möglichkeiten, einen Modus-Schalter auf den x86-CPUs zu machen (was ich hier annahm). Für einen Benutzer, der Funktion genannt wird, besteht die normale Art und Weise darin, einen Aufgabensprung oder -aufruf auszuführen (bezeichnet als Aufgaben-Tore und Ruf-Tore). Bei beiden handelt es sich um einen Task-Schalter (entspricht einem Kontextwechsel). Hinzu kommt noch ein bisschen Verarbeitung vor dem Anruf, die Standardüberprüfung nach dem Anruf und die Rückgabe. Dies rundet das Minimum auf einen sicheren Modus-Schalter ab.

Für Eric Timing, ich bin kein Linux-Experte, aber in den meisten Betriebssystemen, die ich behandelt habe, einfache Systemaufrufe Cache-Daten (wenn es sicher erfolgen kann) im Benutzerraum, um diesen Aufwand zu vermeiden. Und es scheint mir, dass ein getuid() ein Hauptkandidat für solche Daten-Caching wäre. Daher könnte Eric Timing mehr den Overhead der Pre-Switch-Verarbeitung im Benutzerraum widerspiegeln als alles andere.

+1

Es findet kein Daten-Caching statt; deshalb habe ich strace verwendet, um zu überprüfen, ob der Systemaufruf stattfindet. Ein Syscall ist definitionsgemäß ein Aufruf in den Kernel-Space. –

+1

Auch Ihre Behauptung, dass ein Moduswechsel äquivalent zu einem Kontextwechsel ist, ist nicht wahr. Ein Kontextwechsel umfasst das Auslagern des gesamten CPU-Zustands und der Seitentabellen; Dies ist eine wichtige Arbeit, die für Systemaufrufe nicht erforderlich ist. Ein Syscall ist ein einfacher Software-Interrupt (x86-Assembly "int $ 0x80") –

+0

Also gibt es im syscall nur eine Präambel und eine INT-Anweisung? – Juice

Verwandte Themen