{{TODO|Dieser Artikel soll erweitert werden}} Ein '''Symmetrisches Multiprozessorsystem''' (='''SMP''') ist ein System mit einem oder mehreren identischen Prozessoren. Im Gegensatz zu [[NUMA]]-Systemen sind alle Prozessoren auf gleiche Art & Weise mit dem Hauptspeicher verbunden, d.h. es gibt für keinen Prozessor einen von der Geschwindigkeit her bevorzugten/benachteiligten Speicherbereich im Hauptspeicher. == Intel Multiprocessor Specification == Die ''Intel Multiprocessor Specification'' ist ein Standard für [[x86]]- und [[Long Mode|x86-64]]-basierte, symmetrische Multiprozessorsysteme und ist abwärtskompatibel mit existierenden [[x86]]- und [[x86-64]]-Uniprozessorsystemen. Die Spezifikation beschreibt einerseits die Anforderungen an die Hardware und das [[BIOS]] und andererseits die Schritte die notwendig sind, um mit einem [[Betriebssystem]] den Geschwindigkeitsvorteil mehrerer Prozessoren nutzbar zu machen. === Unterteilung der Prozessoren === Beim Start eines Intel-basierten Rechners ist ein Prozessor dafür zuständig, alle Initialisierungen vorzunehmen und schließlich ein Betriebssystem zu booten, wie es auch auf Intel-Uniprozessorsystemen der Fall ist. Dieser Prozessor wird ''Bootstrap Processor'' (BSP) genannt, alle anderen Prozessoren heißen ''Application Processors'' (AP). Die letzteren werden erst aktiviert, wenn das Betriebssystem startet. Das bedeutet, dass die Unterstützung für SMP im Betriebssystem programmiert sein muss, weil die APs sonst im Ruhezustand bleiben und der Rechner somit nur wie ein Uniprozessor-System genutzt werden kann. === Floating Pointer Structure === Der erste Schritt dahingehend ist das Auffinden der ''Floating Pointer Structure''. Diese Struktur wird vom BIOS erstellt und falls sie existiert ist dieses System zur ''Intel Multiprocessor Specification'' kompatibel. ==== Aufbau ==== Die ''Floating Pointer Structure'' liegt an einer 16-Byte Grenze im Speicher und sieht folgendermaßen aus:
http://lowlevel.brainsware.org/wiki/images/SMPFloatingPointer.png
''Floating Pointer Structure''

{| |- ! Feld ! Beschreibung |- | ''Signatur'' | Die Signatur enthält die nicht nullterminierte ASCII-Zeichenkette "_MP_" |- | ''physikalische Adresse'' | Enthält die physikalische Adresse der [[SMP#Configuration Table | Configuration Table]] oder 0x00000000, falls dieses System einer der [[SMP#Default Configuration | Default Configurations]] entspricht. |- | ''Länge'' | Die Größe der Struktur in 16-Byte großen Abschnitten. |- | ''Revision'' | Die Revision der Intel Multiprocessor Specification. Der Wert 0x01 steht für die Version 1.1 und 0x04 für Version 1.4. |- | ''Checksum'' | siehe [[SMP#Auffinden der Struktur | Auffinden der Struktur]] |- | ''Featurebyte 0'' | Der Wert 0x00 gibt an, dass eine [[SMP#Configuration Table | Configuration Table]] vorhanden ist. Jeder andere Wert steht für eine der [[SMP#Default Configuration | Default Configurations]]. |- | ''Featurebyte 1'' | Bit 0-6: reserviert
Bit 7 (IMCRP): Falls dieses Bit gesetzt ist, ist das ''IMCR'' präsent und der ''PIC Mode'' implementiert. Andernfalls ist der ''Virtual Wire Mode'' implementiert. |- | ''Featurebyte 2-4 | reserviert |} ==== Auffinden der Struktur ==== Die ''Floating Pointer Structure'' wird anhand der 4 Signaturbytes und der Checksumme identifiziert. Die Prüfsumme wird berechnet indem man alle Bytes (inklusive des Feldes ''Checksum'') der Struktur aufaddiert. Das Ergebnis dieser Berechnung muss 0x00 sein. Die Struktur befindet sich in mindestens einem der folgenden Speicherbereiche: * In dem ersten Kilobyte der [[Extended BIOS Data Area]] * In dem letzten Kilobyte des Hauptspeichers unterhalb der 1MB Marke (Die Größe des Basisspeichers steht an Offset 0x13 in der [[BIOS Data Area]]), wenn die Addresse der Extended BIOS Data Area nicht definiert ist * Im Adressraum des BIOS ROM (0xF0000 - 0xFFFFF) Die Speicherbereiche sind in exakt dieser Reihenfolge zu durchsuchen. === Configuration Table === === Default Configuration === == Besonderheiten bei der Programmierung == === Multiprozessorsynchronisation (TSL-Instruktion) === Um auf Uniprozessorsystemen effizient wechselseitigen Ausschluss ([[Mutex]]) zu implementieren, wird üblicherweise die ''xchg''-Instruktion verwendet (oder passende API-Funktionen wie [http://msdn.microsoft.com/en-us/library/ms683590(VS.85).aspx InterlockedExchange] unter Windows). Architekturübergreifend wird diese Instruktion als ''TSL'' (Test and Set Lock) oder auch ''TSTS'' (Test and Set) bzw. ''TAS'' (Test and Set) bezeichnet. Dabei liest man mit der Instruktion den alten Wert z.B. in ein Register und schreibt den neuen Wert in den Speicher (z.B. 0 = Mutex verfügbar, 1 = Mutex gelockt). Die Instruktion ist atomar, d.h. kann nicht unterbrochen werden (CPU führt immer ganze Instruktionen aus!). Da Instruktionen ''echt'' gleichzeitig ausgeführt werden können (anstatt hintereinander bei Uniprozessorsystemen), muss diese Instruktion auf Multiprozessorsystemen ebenfalls atomar sein. Eine fehlerhafte Mutex-Implementierung mit nicht-atomaren Operationen könnte z.B. so aussehen: * Der Mutex sei freigegeben (= 0), es kann also ein Prozess in den kritischen Abschnitt eintreten, wenn er den Mutex lockt (d.h. auf 1 setzt) * Nun wollen zwei Threads/Prozesse, die auf verschiedenen CPU's ausgeführt werden, etwa gleichzeitig den Mutex für sich locken * Thread #1 auf CPU #1 liest die Speicherstelle = 0 * Thread #2 auf CPU #2 liest ebenfalls die Speicherstelle = 0 * Thread #1 auf CPU #1 überschreibt den Speicher mit 1 und gibt als alten Wert die gelesene 0 zurück * Thread #2 auf CPU #2 überschreibt den Speicher nochmals mit 1 und gibt als alten Wert die gelesene 0 zurück Nun ist eine [[Race Condition]] aufgetreten: Beide Threads/Prozesse denken nun, dass der Mutex vorher nicht gelockt war und sie nun als einziger Thread/Prozess im kritischen Bereich arbeiten werden. Ganz offensichtlich arbeiten aber in diesem Beispiel nun beide in dem kritischen Abschnitt. Aus diesem Grund wird zur Implementierung die TSL-Instruktion verwendet. Sie ist auch auf SMP-Systemen atomar (vgl. [http://www.intel.com/design/intarch/manuals/243191.htm Intel Spezifikation], S. 3-714), d.h. der sogenannte ''lock''-Präfix wird implizit angenommen, wenn bei der ''xchg''-Instruktion eine Speicherstelle verwendet wird. Der Präfix kann auch explizit angegeben werden - er bewirkt, dass der Speicherbus während der nächsten Instruktion gesperrt wird. Ein Beispiel für eine simple 32-bit TSL-Funktion: ; uint32_t tsl(uint32_t *ptr, uint32_t newValue) _tsl: push ebx mov eax, [esp+12] mov ebx, [esp+8] xchg eax, [ebx] pop ebx ret == siehe auch == * [[APIC]] * [[I/O APIC]] * [[Local APIC]] == Weblinks == * [http://www.intel.com/design/pentium/datashts/242016.htm Intel Multiprocessor Specification] * Kapitel 7 von [http://www.intel.com/design/processor/manuals/253668.pdf Intel® 64 and IA-32 Architectures Software Developer’s Manual] [[Kategorie:Glossar]] [[Kategorie:Tutorials]]