Ich habe versucht, meinen Linux-Server so zu optimieren, dass er 10.000 Threads pro Prozess verarbeitet, während dies derzeit nur 382 sind. Gemäß diesem Artikel wird die folgende Formel verwendet, um die insgesamt möglichen Threads herauszufinden:
number of threads = total virtual memory / (stack size*1024*1024)
Dies bedeutet, dass Threads alle ihre Daten im virtuellen Speicher speichern. Und nach meinem besten Wissen ist virtueller Speicher ein Swap-Speicherplatz auf einem Linux-Computer, der auf einer Festplatte als RAM oder Cache gespeichert ist.
Meine Frage ist also, ob unsere Threads Festplatten verwenden, um ihre Daten zu verarbeiten / zu speichern.
Wenn ja, wirkt sich dies nicht auf die Leistung aus? Können wir die Leistung verbessern, indem wir sie in RAM oder Cache einfügen? Wie?
Wenn nein, wie genau funktionieren Threads?
Aktualisieren:
Nach der Antwort von nutzlos ist der virtuelle Speicher ein System, das ungefähr Folgendes umfasst:
- physischer Speicher (RAM)
- Alle Swap-Dateien, die Sie angehängt haben
- Hardware-Unterstützung für die Übersetzung virtueller in physische Adressen und die Ausgabe von Seitenfehlern, wenn eine virtuelle Adresse nicht im physischen Speicher verfügbar ist
- (Kernel-) Softwareunterstützung für: Verwalten der von dieser Hardware verwendeten Nachschlagetabellen zur Behandlung dieser Seitenfehler durch Abrufen von Seiten aus dem Swap bei Bedarf
Somit befindet sich alles, was sich im virtuellen Speicher befindet, zusammen im RAM (Real Memory) und auf der Festplatte (Swap Files). Und wie James in seiner Antwort erklärt, trifft Kernel die Entscheidung für Ram vs HDD mithilfe von Algorithmen wie LRU.
quelle
Antworten:
Nein, virtueller Speicher ist ein System, das ungefähr Folgendes umfasst:
Es ist Sache des Kernels, sicherzustellen, dass der gewünschte virtuelle Speicher im RAM zwischengespeichert wird, wenn Sie dies möchten - es sei denn, Sie schreiben Ihre eigene VM-Schicht für den Benutzerbereich (wie dies bei Datenbanken häufig der Fall ist, iiuc).
quelle
sar -B
unter Linux).Wenn der Thread tatsächlich ausgeführt wird, muss sich die aktuelle Anweisung und alle vom Thread verwendeten Variablen im physischen Speicher befinden.
Die meisten (tatsächlich fast alle) Programme befinden sich im virtuellen Speicher, und die meisten Programme verwenden den virtuellen Speicher zum Speichern von Variablen.
Virtuelle Adressen, die in Blöcken organisiert sind, die als Seiten bezeichnet werden (dies sind normalerweise 4096- oder 8192-Byte-Blöcke).
Zu jedem Zeitpunkt wird jeder Block des virtuellen Speichers irgendwo im realen Speicher oder auf der Festplatte in dem dafür reservierten "Swap Space" gespeichert.
Ihr Programmcode behandelt virtuelle Adressen, wenn Sie zu einer virtuellen Adresse verzweigen oder den Zugriff auf den Speicher an einer virtuellen Adresse anfordern. Das System (normalerweise auf Hardwareebene) sucht den aktuellen Speicherort der Adressanforderung und ordnet ihn Ihrer virtuellen Adresse zu. Wenn sich die Adresse derzeit auf der Festplatte befindet, wird sie in den realen Speicher verschoben und anschließend die Adresse zugeordnet.
Wenn der gesamte physische Speicher verwendet wird, wenn etwas ausgelagert wird, muss natürlich etwas anderes ausgelagert werden. Daher sucht das System nach der Seite "Am wenigsten verwendet" und kopiert diese auf die Festplatte, bevor die angeforderte Seite kopiert wird.
In modernen Systemen gibt es verschiedene Optimierungen und Tricks im Zusammenhang mit virtuellem Speicher.
quelle
Zunächst müssen Sie mehr über den Computerspeicher lesen , da Ihnen anscheinend die Kenntnisse auf diesem Gebiet fehlen.
Ein Ausführungsthread ist die kleinste Verarbeitungseinheit, die von einem Betriebssystem geplant werden kann. Die Implementierung von Threads und Prozessen unterscheidet sich von Betriebssystem zu Betriebssystem, in den meisten Fällen ist jedoch ein Thread in einem Prozess enthalten. Innerhalb desselben Prozesses können mehrere Threads vorhanden sein und Ressourcen wie den Speicher gemeinsam nutzen, während verschiedene Prozesse diese Ressourcen nicht gemeinsam nutzen.
Threads werden also den verfügbaren Speicher verwenden - unabhängig davon, welche Art von Speicher verfügbar ist. Wie viele Threads Sie starten können, hängt von der Speichergröße ab und davon, wie viel Speicher pro Thread benötigt wird. Wenn der Thread Heap verwendet (nicht nur Stack), benötigt er mehr Speicher. In diesem Fall können Sie weniger Threads starten.
quelle
Die einfache Antwort auf Ihre Frage lautet: Sie verwenden virtuellen Speicher. Alles verwendet virtuellen Speicher mit Ausnahme einiger weniger Prozesse, die sich auf das Betriebssystem beziehen.
Wenn Ihr Thread (oder ein beliebiger Thread in einem beliebigen Prozess) tatsächlich ausgeführt wird, verwendet er physischen Speicher. Die diesem Prozess zugeordneten Speicherseiten werden in den physischen Speicher eingelagert, in dem der Prozessor seine Arbeit erledigt.
quelle
Der virtuelle Speicher ist Ihr RAM plus Ihr Swap-Speicher. Virtuell bedeutet nur, dass die Adresse, die Ihr Programm sieht, sich von der Adresse unterscheidet, die der RAM-Chip sieht. Wenn Sie im Swap auf den Speicher zugreifen müssen, wird er vom Betriebssystem zuerst in den Arbeitsspeicher verschoben. Wenn Sie keinen Austausch wünschen, deaktivieren Sie ihn einfach. Wenn Sie genug RAM haben, brauchen Sie es nicht wirklich.
Abgesehen davon ist das Erhöhen auf 10.000 Threads keine "Optimierung", es sei denn, Sie haben einen 10.000-Kern-Prozessor. Sobald Sie über genügend Threads verfügen, um alle Kerne zu verbrauchen, sowie ein oder zwei Ersatzkerne, wenn diese Threads blockiert sind, verringert das Hinzufügen weiterer Threads die Leistung aufgrund des Switching-Overheads und der Cache-Fehler. Möglicherweise möchten Sie immer noch mehr Threads verwenden, wenn dies Ihre Programmlogik vereinfacht, aber Sie werden die Leistung abwägen.
quelle
top
Befehl erhalten.Wie andere erklärten, ist dies im Allgemeinen falsch. Ein Thread ist eine kostspielige Ressource , insbesondere weil er über einen eigenen Aufrufstapel verfügt (normalerweise ein Megabyte) und weil es sich um eine vom Kernel planbare Aufgabe handelt. Threads sind noch teurer als geöffnete Dateideskriptoren .
Lesen Sie Betriebssysteme: Drei einfache Teile (frei herunterladbares Lehrbuch).
Als Faustregel gilt, dass Sie nicht viele Threads und schon gar nicht viele ausführbare Threads haben möchten. Die Anzahl der ausführbaren Threads sollte im Allgemeinen höchstens der Anzahl der Kerne (oder einem kleinen Vielfachen davon) entsprechen, also höchstens etwa einem Dutzend. Die Anzahl der Threads in einem Prozess kann etwas größer sein. Wenn Sie also keinen sehr expansiven Server haben (mit vielen Prozessorsockeln und -kernen), möchten Sie nicht mehr als ein Dutzend ausführbare Threads und hundert Threads (die meisten davon inaktiv) in Ihrem Prozess (auf Ihrem Desktop) haben. .
Unter Linux sind Threads und Prozesse sehr ähnlich (da beide vom Klon (2) erstellt werden können ) und beide vom Kernel geplante Aufgaben sind. Tatsächlich plant der Kernel-Scheduler Aufgaben, die Threads innerhalb eines Multithread-Prozesses oder der einzelne Haupt-Thread eines Single-Thread-Prozesses (in diesem Fall werden Sie diesen einzelnen Thread als "Prozess" bezeichnen) oder Kernel-Threads sein können. Sie möchten wahrscheinlich nicht mehr als tausend planbare Aufgaben auf Ihrem Desktop-System haben.
Unter Linux ist ein Prozess einfach eine Gruppe von Threads, die denselben virtuellen Adressraum verwenden (und einige andere Dinge gemeinsam nutzen, z. B. die Dateideskriptortabelle usw.). Einige Prozesse haben nur einen Thread.
Ein virtueller Adressraum wird von Wikipedia als definiert
(Siehe auch diese Antwort, in der erklärt wird, dass die Terminologie nicht universell ist und in einigen Microsoft-Dokumentationen eine andere und inkompatible Definition verwendet wird.)
Unter Linux ist proc (5) hilfreich, um den virtuellen Adressraum einiger Prozesse zu verstehen. Versuchen Sie beide
cat /proc/self/maps
undcat /proc/$$/maps
in einem Terminal. Siehe auch dies und pmap (1) & ps (1) & top (1) .Alle User-Space-Programme werden in einem bestimmten Prozess ausgeführt und verwenden virtuellen Speicher, sodass jeder Prozess seinen eigenen virtuellen Adressraum hat. Der physische RAM ist eine Ressource, die vom Linux-Kernel verwaltet wird, und Anwendungen haben keinen direkten Zugriff auf den RAM (außer durch mmap (2) -ing
/dev/mem
, siehe mem (4) ).Ein Prozess verwendet also nicht direkt RAM. Es verwendet virtuellen Speicher und verfügt über einen eigenen virtuellen Adressraum. Der Kernel verwendet Paging physischen RAM zu verwalten Seiten und den virtuellen Adressraum und die Verfahren liefern Abstraktionen . Zu jeder Zeit (auch wenn Ihr Prozess inaktiv ist oder ausgeführt wird) kann der Kernel einige Seiten ausblenden (z. B. sie auf der Festplatte austauschen). Der Kernel konfiguriert die MMU (und behandelt Hardware- Ausnahmen bei Seitenfehlern in einigen Interrupt-Handlern , indem er entweder die Seite von der Festplatte abruft oder einen Segmentierungsfehler an den Prozess weitergibt, siehe Signal (7) ).
Sie könnten grüne Threads über System-Threads haben (aber grüne Thread-Bibliotheken sind schwer zu implementieren und zu debuggen). Schauen Sie sich die in Go verwendeten Goroutinen an, um ein ausgefallenes Beispiel zu finden. Siehe auch setcontext (3) .
Manchmal kann Ihr System mit Thrashing experimentieren . Dies geschieht, wenn der gesamte virtuelle Speicher (der von allen Prozessen benötigt wird) den verfügbaren physischen RAM um einen großen Faktor überschreitet. Dann reagiert Ihr Computer nicht mehr. Lesen Sie mehr über die Größe des residenten Satzes , das Anforderungs-Paging , den Arbeitssatz , die Speicherüberlastung und die ASLR .
Siehe auch -für Linux- Gabel (2) , Klon (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , Anmeldeinformationen (7) , pthreads (7) , Futex (7) , Fähigkeiten (7) .
quelle