Jump to content

User:WerWieWiki/sandbox

From Wikipedia, the free encyclopedia

Externes Sortieren beschreibt Sortieralgorithmen, welche auf sehr große Datenmengen ausgelegt sind. Algorithmen die auf großen Datenmenge arbeiten, die nicht mehr in den Hauptspeicher passen, werden allgemein als External Memory Algorithmen bezeichnet. In der Analyse klassischer Sortieralgorithmen (z.B. Quicksort) wird meist keine Speicherhierarchie bzw. der Zugriff auf Daten auf unterschiedlich schnellen Datenträgern berücksichtigt. Allerdings ist der Aufbau und die Hierarchie des Speichers sowie der Umgang der Algorithmen mit diesem für die Performance beim Sortieren von großen Datenmengen entscheident.

Parallel Disk Model

[edit]

Ein gebräuchliches Modell zur Betrachtung von External Memory Algorithmen ist das Parallel Disk Model (PDM).[1] Dieses verfügt über einen Hauptspeicher der Größe und einen oder mehreren externen Speicher unbegrenzter Größe, die sogenannten Disks. Auf diesen finden die zu sortierenden Daten der Größe Platz. Oftmals wird zur Vereinfachung die Anzahl der Disks angenommen und das vereinfachte Modell als External Memory Model (EMM) bezeichnet. Auch Aggarwal und Vitter stellten das Modell ursprünglich mit einer einzelnen Disk, aber mehreren parallelen Schreib-Lese-Köpfen vor.[2] Der Hauptspeicher wie auch der externen Speicher verfügen über eine Blockgröße . Mit einer IO-Operation, kann ein Block pro Disk in den Hauptspeicher geladen oder in den externen Speicher zurückgeschrieben werden. Zur besseren Übersicht werden außerdem die Eingabegröße sowie die Größe des Hauptspeichers in Blöcken angegeben. Im Gegensatz zur Analyse klassischer Sortieralgorithmen wird die Performance eines Algorithmus nicht an der Anzahl aller Operationen gemessen, sondern nur durch die Anzahl der IO-Operationen angegeben.

Untere Schranke

[edit]

Für das Sortieren im PDM kann eine allgemeingültige Schranke für die Anzahl der IO-Operationen angegeben werden.[1] Diese ist im Fall einer einzelnen oder mehrerer Disks () gegeben durch:

In der Praxis ist eine kleine Konstante. Für den untypischen Fall gilt diese Schranke lediglich für vergleichsbasierte Verfahren.

Algorithmen

[edit]

Merge Sort

[edit]

An den klassischen Merge Sort angelehnt ist der External Memory Merge Sort.[1][3] Zunächst soll der Algorithmus für betrachtet werden. Es werden nacheinander Datensegmente bestehend aus Blöcken in den Hauptspeicher geladen, dort sortiert und als sogenannter Run zurück in den externen Speicher geschrieben werden. Die Runs im externen Speicher werden anschließend mittels eines K-Way Merges auf Rekursionsebenen zusammengefasst.

Vereinfachte Darstellung des Merge Sorts. Zuerst werden die einzelnen Runs im Hauptspeicher sortiert, anschließend werden die Runs gemerged.
 for j=1 to n/M
     Lade nächstes Datensegment der Größe  in Hauptspeicher
     Sortiere Daten im Hauptspeicher
     Schreibe sortierte Daten als run  auf externen Speicher
 end
 
 for i=1 to 
     for j=1 to 
         Lade die jeweils ersten Blöcke der runs  in Merge-Buffer
         while Merge-Buffer nicht leer
             Merge runs 
             Schreibe Output-Buffer in externen Speicher falls voll
             Lade nächsten Block in Hauptspeicher falls ein Merge-Buffer bereits komplett gemerged
         end
     end
 end

Um mehrere parallele Disks möglichst effizient zu nutzen und die oben beschriebene Schranke einzuhalten, müssen in jedem IO-Schritt möglichst Blöcke bewegt werden. Zum effizienten Schreiben der Blöcke zurück auf die Disks wird daher die Größe des internen Buffers im Hauptspeicher, der die gemergten Elemente enthält, auf Blöcke erweitert. Um auch beim Lesen einen höheren Durchsatz zu gewährleisten wird außerdem ein Prefetching Buffer hinzugefügt. Wurden die Elemente in den vorherigen Schritten geschickt auf den einzelnen Disks verteilt und eine geeignete Prefetching Strategie gewählt genügt eine Buffergröße von Blöcken.

Distribution Sort

[edit]

Analog zum Merge Sort ist auch der Distribution Sort ein rekursiver Algorithmus.[1][3] Die Daten sollen nach Partitionierungs Elementen in Buckets eingeteilt werden. Dabei gilt, dass alle Elemente innerhalb eines Buckets kleiner sind als jedes Element im darauf Folgenden. Diese Partitionierung wird dann rekusiv für die einzelnen Buckets wiederholt. Sind die Buckets klein genug um jeweils komplett in den Hauptspeicher geladen werden zu können, werden sie dort sortiert. Die Konkatenation der sortierten Buckets bildet somit die sortierte Reihenfolge der gesamten Daten.

Die Wahl der Partitionierungs Elemente ist entscheidend um möglichst gleich große Buckets zu erhalten und somit eine gute Performance zu gewährleisten. Dies kann beispielsweise auf probabilistische Art und Weise erfolgen. Eine kleine, zufällige Menge an Elementen wird sortiert und und die Partitionierungs Elemente aus dieser ausgewählt. Die Größe der Menge wird so gewählt, dass die Sortierung dieser für die Anzahl an IO-Operationen vernachlässigbar ist und keinen Einfluss auf die Schranke hat. Bei guter Partitionierung beträgt die Rekursionstiefe . Da für jedes Bucket ein Buffer im Hauptspeicher benötigt wird, kann durch nach oben abgeschätzt werden.

Um die oben gegebene Schranke zu erfüllen dürfen somit auf jeder Rekursionsebene lediglich IO-Operationen ausgeführt werden. Um ein Bucket effizient in den Hauptspeicher zu laden, müssen dessen Blöcke zuvor gleichmäßig auf die verschiedenen Disks verteilt worden sein. Die zu den verschiedenen Buckets gehörenden Blöcke werden entweder gemeinsam als ein Stripe aus dem Output-Buffer im Hauptspeicher auf den externen Speicher geschrieben oder es wird ein Stripe pro Bucket erstellt. Im Falle eines Stripes pro Bucket kann mit Hilfe von Randomized Cycling dafür gesorgt werden, dass die nächsten Blöcke der verschiedenen Buckets auf möglichst unterschiedliche Disks geschrieben werden müssen. Diese Variante wird auch Randomized Cycling Distribution Sort genannt.

Anwendungen

[edit]

Grundsätzlich nehmen Operationen zur Sortierung einen großen Teil des Rechenaufwands ein.[3] In den letzten Jahren sind die Datenmengen auf denen gerechnet wird stetig größer geworden.[1] Zur Bewältigung dieser Datenmengen sind External Memory Algorithmen nötig. Effizientes Externes Sortieren hat dabei eine besondere Bedeutung, da viele External Memory Algorithmen auf Sortierverfahren beruhen.

Referenzen

[edit]
  1. ^ a b c d e Vitter, Jeffrey Scott (2008). "Algorithms and data structures for external memory". Foundations and Trends in Theoretical Computer Science. 2 (4): 30–474.
  2. ^ Aggarwal, Alok; Vitter, Jeffrey Scott (1988). "The input/output complexity of sorting and related problems" (PDF). Communications of the ACM. 31 (9): 1116–1127. doi:10.1145/48529.48535. S2CID 6264984.
  3. ^ a b c Knuth, Donald (1973). The Art of Programming, Vol. 3 (Sorting and Searching). Addison-Wesley.