Dieser Artikel wurde maschinell übersetzt.

Paralleles Computing

Datenverarbeitung: Parallelismus und Leistung

Johnson M. Hart

Downloaden des Codebeispiels

Verarbeiten von Datensammlungen ist eine grundlegende computing Aufgabe und eine Reihe von praktischen Problemen sind grundsätzlich parallele, potenziell aktivieren, verbesserte Leistung und Durchsatz auf Mehrkern-Systemen. Ich werde mehrere unterschiedliche Windows-basierte Methoden zum Lösen von Problemen mit einem hohen Grad an Datenparallelität vergleichen.

Kapitel 9 “ LINQ to Objects Using c# 4.0 ” Troy Magennis Buch (Addison-Wesley, 2010) ist Benchmark für diesen Vergleich verwendet wird ein Problem suchen (“ Geonames ”). Alternativen Lösungen sind:

  • Parallele Language Integrated Query (PLINQ) und c# 4.0, mit und ohne Erweiterungen des ursprünglichen Codes.
  • Windows systemeigenen Code, wobei C, die Windows-API-Threads und Memory-mapped-Dateien.
  • Windows c# / Microsoft .NET Framework multithreaded Code.

Der Quellcode für alle Lösungen ist auf meiner Website (jmhartsoftware.com ) verfügbar. Andere Parallelität Techniken, wie z. B. dem Windows Task Parallel Library (TPL), werden nicht direkt, untersucht, obwohl PLINQ auf die TPL schichtweise angelegt ist.

Vergleichen und Bewerten von alternative Lösungen

Die Bewertungskriterien Lösung in der Reihenfolge der Wichtigkeit, sind:

  • Total Leistung hinsichtlich der verstrichenen Zeit zum Ausführen der Aufgabe.
  • Skalierbarkeit mit dem Grad der Parallelität (Anzahl der Aufgaben) core Count und Daten Auflistungsgröße.
  • Code der Einfachheit halber, Eleganz, einfache Wartung und ähnliche immateriellen Faktoren.

Zusammenfassung der Ergebnisse

In diesem Artikel erfahren, die für ein repräsentatives Benchmark-Problem suchen:

  • Sie können die Mehrkern-64-Bit-Systeme zur Verbesserung der Leistung in viele Datenverarbeitung Probleme erfolgreich ausnutzen und PLINQ Teil der Lösung sein.
  • Wettbewerb, skalierbare PLINQ Leistung erfordert indizierte Auflistung Datenobjekte;Unterstützung von IEnumerable-Schnittstelle ist nicht ausreichend.
  • Die C#- / .NET- und systemeigenen Codelösungen sind am schnellsten.
  • Die ursprüngliche PLINQ-Lösung ist langsamer, um einen Faktor von fast 10 und es nicht über zwei Aufgaben skaliert, während die andere Lösungen auch bis zu sechs Vorgänge mit sechs Kerne (das Maximum getestet) skalieren. Code-Erweiterungen verbessern die ursprüngliche Lösung jedoch erheblich.
  • Der PLINQ-Code ist die einfachste und am häufigsten in jeder Hinsicht elegant, da LINQ speicherresidenten und externe Daten die Fähigkeit, deklarative Abfrage bietet. Der systemeigene Code ist ungainly, und die C#- / .NET Code ist wesentlich besser als – aber nicht so einfach wie – der PLINQ-Code.
  • Alle Methoden Skala mit Datei Größe von den Beschränkungen des physikalischen Speichers Test System.

Die Benchmark-Problem: Geonames

Die Idee für diesen Artikel stammt aus Kapitel 9 ’ Magennis LINQ Buches, das PLINQ durch Suchen einer geografischen Datenbank enthält mehr als 7.25 Millionen Ländernamen in einer 825-MB-Datei (die für alle 1.000 Benutzer mehr als ein Standort ist) veranschaulicht. Jeder Stelle Name wird durch ein UTF-8 (en.wikipedia.org/wiki/UTF-8 ) Text Zeile Datensatz (Variable Länge) mit mehr als 15 tabstoppgetrenntem Datenspalten dargestellt. Hinweis*: Die UTF-8-Codierung, die eine Registerkarte (0 x 9) versichert oder Zeilenvorschub (0xA) Wert wird nicht als Teil einer Multi-Byte-Sequenz auftreten;Dies ist wichtig für verschiedene Implementierungen.*

Magennis Geonames Programm implementiert eine hartcodierte Abfrage Identifizieren aller Standorte mit einer Erweiterung (Spalte 15) mehr als 8.000 Meter, Anzeigen der Standortname, Land und Erhöhung, sortiert nach Erhöhung zu verringern. Falls Sie sich wundern, 16 solche Speicherorte sind und Mt. Everest ist die höchste am 8,848 Meter.

Magennis meldet, welchem Zeitraum 22.3 Sekunden (ein Kern) und 14.1 Sekunden (zwei Kerne). Erfahrung (z. B. Siehe meinen Artikel “ Windows Parallelität, fast Datei suchen und spekulative Verarbeitung ” informit.com/articles/article.aspx?p=1606242-) zeigt, dass die Dateien dieser Größe in wenigen Sekunden und Leistung verarbeitet werden können skaliert gut mit der Anzahl der zentrale. Ich entschied mich deshalb zu versuchen, dieses Erlebnis zu replizieren und auch versuchen, Magennis PLINQ-Code für eine bessere Leistung zu verbessern. Die anfänglichen PLINQ-Erweiterungen fast verdoppelt die Leistung, aber nicht die Skalierbarkeit verbessern;Weitere Verbesserungen jedoch yield Leistung fast so gut wie systemeigene und c# multithreaded Code.

Dieser Benchmark ist aus verschiedenen Gründen interessant:

  • Betreff (geografische Orte und Attribute) ist naturgemäß interessant, und es ist einfach, die Abfrage zu verallgemeinern.
  • Es gibt ein hoher Grad an Datenparallelität;im Prinzip kann jeden Datensatz gleichzeitig verarbeitet werden.
  • Die Dateigröße von heutigen Standards gering ist, aber es ist einfach, einfach durch Verketten der Datei Geonames allCountries.txt selbst mehrere Male mit größeren Dateien zu testen.
  • Die Verarbeitung ist nicht statusfrei;ist es erforderlich, die die Begrenzungen für Zeile und das Feld bestimmen, um die Datei zu partitionieren, und die Zeilen zum Identifizieren der Felder 
individual verarbeitet werden müssen.

Eine Annahme: Wird davon ausgegangen, dass die Anzahl der erkannten Datensätze (in diesem Fall mehr als 8.000 Meter Speicherorten), damit die Zeit sortieren und Anzeigen sind minimal, relativ zu den allgemeinen gering ist, ist jedes Byte muss Verarbeitungszeit.

Ein weiteres Annahme: Die Leistungsergebnisse repräsentieren die Ausführungsdauer von speicherresidenten Datenauflistungen, z. B. von einem Programm vor Schritt erzeugten Daten verarbeitet. Beim Benchmark-Programm liest eine Datei, aber der Test Programme mehrmals ausgeführt werden, um sicherzustellen, dass die Datei speicherresidente ist. Allerdings erwähnt wird die Zeit für die Datei ursprünglich geladen werden, und diesmal entspricht ungefähr dem für alle Lösungen.

Vergleich der Leistung

Das erste Testsystem ist ein sechs grundlegenden desktop unter Windows 7 (AMD Phenom II, 2,80 GHz, 4 GB RAM). Später werde ich Ergebnisse für drei anderen Systemen mit Hyperthreading oder HT (en.wikipedia.org/wiki/Hyper-threading ) vorstellen und anderen zentralen zählt.

Abbildung 1 enthält die Ergebnisse für sechs verschiedene Geonames-Lösungen mit verstrichene Zeit (Sekunden) als eine Funktion der “ Grad der Parallelisierung ” oder DoP (die Anzahl der parallelen Tasks, die höher ist als die Anzahl von Prozessoren festgelegt werden kann);das Testsystem hat sechs Kerne, aber die Implementierungen der DoP zu steuern. Sechs Vorgänge sind optimal;Verwendung von mehr als sechs Tasks beeinträchtigt die Leistung. Alle Tests verwenden Sie die ursprüngliche Geonames 825 MB allCountries.txt-Datendatei.

image: Geonames Performance as a Function of Degree of Parallelism

Abbildung 1 Geonames Leistung als eine Funktion der Grad an Parallelität

Die Implementierungen sind (umfassendere Erläuterungen werden folgen):

  1. Geonames Original. Dies ist die ursprüngliche PLINQ-Projektmappe Magennis. Die Leistung nicht Wettbewerb und nicht mit der Anzahl der Prozessoren skaliert werden.
  2. Geonames-Hilfsprogramm. Dies ist eine Version mit erhöhter Leistung von Geonames Original .
  3. Geonames MMChar. Dies war ein erfolgloser Versuch zur Verbesserung der Geonames Helper mit einer Speicherabbilddatei Klasse ähnelt, die in Geonames Threads verwendet. Hinweis*: Speicherzuordnung kann es sich um eine Datei verwiesen werden, als ob er im Speicher ohne explizite e/a-Vorgänge wurde, und es kann Leistungsvorteile bieten.*
  4. Geonames MMByte. Diese Lösung ändert MMChar zum Verarbeiten einzelner Bytes der Eingabedatei, während die vorherigen drei Lösungen UTF-8-Zeichen in Unicode (mit 2 Bytes) zu konvertieren. Die Leistung ist das beste aus der ersten vier Lösungen und mehr als verdoppeln, Geonames Original-.
  5. Geonames Threads verwenden nicht PLINQ. Dies ist die C#- / .NET Implementierung mithilfe von Threads und eine Datei mit zugewiesenem Speicher. Die Leistung ist schneller als Index (das nächste Element) und über native identisch. Diese Lösung und Geonames systemeigen bieten die beste Skalierbarkeit der Parallelität.
  6. Geonames Index. Diese Lösung PLINQ eine Vorverarbeitung die Datendatei (erfordern etwa neun Sekunden) eine speicherresidentes List < Byte [] > Erstellenfür die weitere Verarbeitung der PLINQ-Objekt. Die Kosten für die Vorverarbeitung kann über mehrere Abfragen, wodurch Leistung, die nur etwas langsamer als Geonames systemeigen und Geonames Threads verteilt werden.
  7. Geonames systemeigen ( Abbildung 1 nicht dargestellt) PLINQ nicht verwenden. Dies ist die C#-Windows-API-Implementierung mit Threads und eine Datei mit zugewiesenem Speicher wie in Kapitel 10 meines Buchs “ Windows System Programming ” (Addison-Wesley, 2010). Vollständige Compileroptimierung ist entscheidend für diese Ergebnisse;die Standard-Optimierung bietet nur etwa die Hälfte die Leistung.

Alle Implementierungen sind 64-Bit-Builds. 32-Bit-Builds funktioniert in den meisten Fällen, aber für die größere Dateien (siehe Abbildung 2 ) fehlschlagen. Abbildung 2 zeigt die Leistung mit DoP 4 und größere Dateien.

image: Geonames Performance as a Function of File Size

Abbildung 2 Geonames Leistung als eine Funktion der Datei

In diesem Fall ist das Testsystem vier Kerne (AMD Phenom Quad-Core, 2.40 GHz, 8 GB RAM). Größeren Dateien wurden durch Verketten mehrerer Kopien der ursprünglichen Datei erstellt. Abbildung 2 Zeigt, nur die drei am schnellsten Lösungen, z. B. Geonames Index – die schnellste PLINQ-Lösung (keine Datei vorverarbeiten gezählt) – und Leistung mit der Dateigröße bis zu den Grenzen des physikalischen Speichers skaliert.

Ich werde nun Implementierungen zwei bis sieben beschreiben und die PLINQ-Techniken ausführlicher erläutert. Folgt, dass ich die Ergebnisse ansprechen werde auf anderen Systemen zu testen und die Ergebnisse zusammenfassen.

Erweiterte PLINQ-Lösungen: Geonames-Hilfsprogramm

Abbildung 3 zeigt Geonames Helper mit vorgenommenen Änderungen (in Fettschrift) -Code Geonames Original.

Abbildung 3 Geonames-Hilfsprogramm mit hervorgehobenen Änderungen am Original PLINQ-Code

class Program
{
  static void Main(string[] args)
  {
    const int nameColumn = 1;
    const int countryColumn = 8;
    const int elevationColumn = 15;

    String inFile = "Data/AllCountries.txt";
    if (args.Length >= 1) inFile = args[0];
        
    int degreeOfParallelism = 1;
    if (args.Length >= 2) degreeOfParallelism = int.Parse(args[1]);
    Console.WriteLine("Geographical data file: {0}.
Degree of Parallelism: {1}.", inFile, degreeOfParallelism);

    var lines = File.ReadLines(Path.Combine(
      Environment.CurrentDirectory, inFile));

    var q = from line in 
      lines.AsParallel().WithDegreeOfParallelism(degreeOfParallelism)
        let elevation = 
          Helper.ExtractIntegerField(line, elevationColumn)
        where elevation > 8000 // elevation in meters
        orderby elevation descending
        select new
        {
          elevation = elevation,
          thisLine = line
         };

    foreach (var x in q)
    {
      if (x != null)
      {
        String[] fields = x.thisLine.Split(new char[] { '\t' });
        Console.WriteLine("{0} ({1}m) - located in {2}",
          fields[nameColumn], fields[elevationColumn], 
          fields[countryColumn]);
      }
    }
  }
}

Wie viele Leser nicht mit PLINQ und c# 4.0 vertraut werden können, werde ich einige Kommentare über Abbildung 3 , einschließlich Beschreibungen der Verbesserungen ermöglichen:

  • Zeilen 9 bis 14 ermöglichen den Benutzer den Namen der Eingabedatei und der Grad der Parallelität (die maximale Anzahl gleichzeitiger Tasks) in der Befehlszeile angeben;Diese Werte sind in der ursprünglichen hartcodiert.
  • Geben Sie Zeilen Zeilen 16-17 beginnen, lesen die Zeilen der Datei asynchron und implizit als C#-String-Array. Die Werte für Zeilen werden bis 19-27-Zeilen nicht verwendet werden. Andere Lösungen, z. B. mit Geonames MMByte, verwenden eine andere Klasse mit eigenen ReadLines-Methode, und diese Codezeilen sind die nur Zeilen, die geändert werden müssen.
  • Zeilen 19-27 sind LINQ-Code zusammen mit der Erweiterung PLINQ AsParallel. Der Code ähnelt dem SQL und Variable “ Q ” wird implizit als Array von Objekten, bestehend aus Ausweitung ganze Zahl und eine Zeichenfolge eingegeben. Beachten Sie, dass PLINQ die Threadverwaltung Arbeit ausführt;Die AsParallel-Methode ist, die erforderlich ist, seriellen LINQ-Code zu PLINQ Code zu machen.
  • Zeile 20. Abbildung 4 zeigt die Helper.ExtractIntegerField-Methode. Das ursprüngliche Programm verwendet die String.Split-Methode ähnlich an, die zum Anzeigen der Ergebnisse in Zeile 33 ( Abbildung 3 ) verwendet. Dies ist der Schlüssel für eine bessere Leistung von Geonames Helper im Vergleich zu mit Geonames Original, wie es nicht mehr erforderlich, die String-Objekte für jedes Feld in jeder Zeile reserviert ist.

Abbildung 4 Geonames-Hilfsklasse und ExtractIntegerField Methode

class Helper
{
  public static int ExtractIntegerField(String line, int fieldNumber)
  {
    int value = 0, iField = 0;
    byte digit;

    // Skip to the specified field number and extract the decimal value.
foreach (char ch in line)
    {
      if (ch == '\t') { iField++; if (iField > fieldNumber) break; }
      else
      {
        if (iField == fieldNumber)
        {
          digit = (byte)(ch - 0x30);  // 0x30 is the character '0'
          if (digit >= 0 && digit <= 9) 
            { value = 10 * value + digit; }
          else // Character not in [0-9].
Reset the value and quit.
{ value = 0; break; }
        }
      }
    }
    return value;
  }
}

Beachten Sie, dass die in Zeile 19 verwendete AsParallel-Methode mit einem beliebigen IEnumerable-Objekt verwendet werden kann. Wie bereits erwähnt, wird Abbildung 4 Helper-Klasse ExtractIntegerField-Methode. Es einfach extrahiert und des angegebenen Feldes (in diesem Fall Erhöhung) wertet Bibliothek-Methoden, um Leistung zu vermeiden. Abbildung 1 zeigt an, dass diese Verbesserung die Leistung mit DoP 1 verdoppelt.

Geonames MMChar und Geonames MMByte

Geonames MMChar stellt einen erfolglosen Versuch zum Verbessern der Leistung durch Zuordnen der Eingabedatei mit eine benutzerdefinierte Klasse FileMmChar Speicher. Geonames MMByte, ergibt jedoch bedeutende Vorteile, wie die Eingabedatei Bytes in Unicode erweitert werden nicht.

MMChar erfordert eine neue Klasse FileMmChar, die die IEnumerable <String> unterstütztSchnittstelle. Die FileMmByte-Klasse ähnelt und befasst sich mit Byte []-Objekte statt String-Objekte. Die nur bedeutende Codeänderung besteht darin, Abbildung 3 , Linien 16-17, die jetzt sind:

var lines = FileMmByte.ReadLines(Path.Combine(
    Environment.CurrentDirectory, inFile));

Der Code für

public static IEnumerable<byte[]> ReadLines(String path)

unterstützt die IEnumerable < Byte [] >Schnittstelle in FileMmByte erstellt ein FileMmByte-Objekt und ein IEnumerator < Byte [] >Objekt, das die zugeordnete Datei für die einzelnen Zeilen durchsucht.

Beachten Sie, dass die Klassen FileMmChar und FileMmByte “ unsichere ”, da Sie erstellen und Verwenden von Zeigern auf die Dateien zugreifen und Sie c# verwenden / systemeigenen code Interoperabilität. Die Zeiger-Verwendung ist jedoch in einer separaten Assembly isoliert, und der Code verwendet, Arrays, sondern Zeiger zu dereferenzieren. Die .NET Framework-4 MemoryMappedFile-Klasse helfen nicht, da Accessorfunktionen verwenden Sie zum Verschieben von Daten aus dem Speicher zugeordnet ist.

Geonames systemeigen

Geonames systemeigen nutzt die Windows-API, Threads und Speicher-Dateizuordnung. Die grundlegenden Code-Muster werden in Kapitel 10 der “ Programming Windows System. ” beschrieben. Das Programm die Threads muss direkt verwalten und muss auch sorgfältig die Datei in den Speicher zugeordnet. Die Leistung ist wesentlich besser als alle Implementierungen von PLINQ außer Geonames Index .

Es ist jedoch ein wichtiger Unterschied zwischen das Problem Geonames und eine einfache, statusfreie Dateisuche oder die Transformation. Die Herausforderung besteht darin, Partition die Eingabedaten mit verschiedene Partitionen, die verschiedenen Vorgängen zuweisen die richtige Methode zu ermitteln. Es gibt keine Möglichkeit die Linien für die Begrenzung ermitteln, ohne dass die gesamte Datei, so ist nicht möglich, eine Partition mit fester Größe jeder Aufgabe zuweisen. Die Lösung ist jedoch einfacher, wenn mit DoP 4 dargestellt:

  • Unterteilen Sie die Eingabedatei in vier gleich Partitionen, beginnen Sie mit der Partition Speicherort für jeden Thread als Teil der Thread Funktionsargument mitgeteilt.
  • Jeder Thread haben und dann alle Zeilen (Datensätze) verarbeiten, Starten in der Partition. Dies bedeutet, dass ein Thread wahrscheinlich in die nächste Partition durchsucht werden, um die Verarbeitung der letzten Zeile abgeschlossen, die in der Partition.

Geonames Threads

Geonames Threads verwendet Geonames systemeigen dieselbe Logik;in der Tat ist Teil des Codes identisch oder fast identisch. Allerdings Lambda-Ausdrücke, Erweiterungsmethoden, Container und andere C#- / .NET Features der Codierung erheblich vereinfachen.

Wie bei MMByte -und MMChar-Zuordnung die Speicher “ unsichere ” Klassen und c# erfordert / systemeigenen code Interoperabilität für Zeiger auf den zugeordneten Speicher verwenden. Der Aufwand ist jedoch sinnvoll, weil -Leistung Geonames ThreadsGeonames systemeigen Leistung mit viel einfacher Code identisch ist.

Geonames Index

Die PLINQ-Ergebnisse ( Original , HelperMMChar und MMByte ) sind im Vergleich zu den systemeigenen von und .NET Threads Ergebnisse disappointing. Gibt es eine Möglichkeit zum Ausnutzen der Einfachheit und Eleganz von PLINQ, ohne Einbußen bei der Leistung?

Obwohl es unmöglich ist, bestimmen, genau wie PLINQ die Abfrage ( Abbildung 3 Zeilen 16-27) verarbeitet, ist es wahrscheinlich, dass PLINQ keine gute Möglichkeit zum Partitionieren von eingegebenen Zeilen für parallele Verarbeitung durch separate Aufgaben verfügt. Als eine Hypothese arbeiten wird davon gegangen Sie aus, dass die Partitionierung der Ursache des Leistungsproblems PLINQ sein kann.

Magennis Adressbuch (Seiten. 276 279), das Zeilen String-Array unterstützt die IEnumerable <String>Schnittstelle (Siehe auch John-scharf Buch “ Microsoft Visual c# 2010 Step by Step ” [Microsoft Press, 2010], Kapitel 19). Wird jedoch Zeilen ist nicht indizierte, so dass PLINQ wahrscheinlich verwendet “ aufteilen, partitionieren. ” Darüber hinaus sind die IEnumerator.MoveNext Methoden für Klassen FileMmChar und FileMmByte langsam, weil Sie, benötigen um alle Zeichen zu scannen, bis die nächste neue Zeile gefunden wird.

Was geschieht, wenn das Zeilen vom Typ String Array indiziert wurden? Konnten wir PLINQ verbessert die Leistung, besonders wenn ergänzt durch Zuordnen der Eingabedatei Arbeitsspeicher? Geonames Index zeigt an, dass dieses Verfahren verbessert die Leistung, woraus sich Ergebnisse mit systemeigenem Code vergleichbar. In der Regel jedoch entweder der erforderlichen Weise Kosten zum Verschieben von Zeilen in einer Liste im Arbeitsspeicher oder Array indiziert wird (die Kosten kann dann werden verteilt über mehrere Abfragen), oder die Datei oder einer anderen Datenquelle bereits indiziert, vielleicht während der Generierung in einem früheren Schritt für die Anwendung, eliminiert die Vorverarbeitung Kosten.

Im Vorfeld Indizierungsvorgang ist einfach;nur Zugriff auf jede Zeile einzeln an, und fügen Sie die Zeile in einer Liste. Verwenden Sie das Listenobjekt in Zeilen 16-17, wie dargestellt in Abbildung 3 und in dieser Codeausschnitt, der die Vorverarbeitung angezeigt wird:

// Preprocess the file to create a list of byte[] lines
List<byte[]> lineListByte = new List<byte[]>();
var lines = 
    FileMmByte.ReadLines(Path.Combine(Environment.CurrentDirectory, inFile));
// ...
Multiple queries can use lineListByte
// ....
foreach (byte[] line in lines) { lineListByte.Add(line); }
// ....
var q = from line in lineListByte.AsParallel().
WithDegreeOfParallelism(degreeOfParallelism)

Beachten Sie, dass es etwas effizienter ist, die Daten weiter durch das Konvertieren der Liste in ein Array zu verarbeiten, obwohl dies die Vorverarbeitung Zeit erhöht.

Eine abschließende Verbesserung der Leistung

Geonames Index die Leistung verbessert werden kann noch weiter durch die Felder in jeder Zeile indizieren, damit ExtractIntegerField-Methode nicht alle Zeichen in einer Zeile aus dem angegebenen Feld durchsucht werden muss.

Die Implementierung Geonames IndexFields ändert die ReadLines-Methode, sodass eine zurückgegebene Zeile ein Objekt mit einem Byte []-Array und ein Uint []-Array mit die Speicherorten der einzelnen Felder ist. Dies führt zu einer Leistungssteigerung von 33 Prozent über Geonames Index und bringt die Leistung relativ nahe an die systemeigenen und c# / .NET Lösungen. (Geonames IndexFields ist im Codedownload enthalten.) Darüber hinaus ist es jetzt viel einfacher erstellen allgemeinere Abfragen, wie die einzelnen Felder verfügbar sind.

Einschränkungen

Die effizienten Lösungen, die alle speicherresidenten Daten erfordert und die Leistungsvorteile nicht zu sehr großen Datensammlungen erweitern. “ Sehr große ” bezeichnet in diesem Fall Datengrößen diesen Ansatz die Größe des physischen Speichers. Im Beispiel Geonames konnte die Datei 3,302 MB (vier Kopien der ursprünglichen Datei) auf 8 GB-Testsystem verarbeitet werden. Ein Test mit acht verketteten Kopien der Datei wurde jedoch mit den Lösungen sehr langsam.

Wie bereits erwähnt, ist Leistung auch am besten, wenn die Dateien sind “ live, ” in dem Sinn, dass Sie vor kurzem zugegriffen haben, und sind wahrscheinlich im Arbeitsspeicher. Paging in der Datendatei während der ersten Ausführung kann mindestens 10 Sekunden lang und ist vergleichbar mit der Indizierungsvorgang im früheren Codeausschnitt.

Zusammenfassend lässt sich sagen wenden Sie die Ergebnisse in diesem Artikel auf speicherresidente Datenstrukturen und heutigen Speicher Größen und Preise ermöglichen deutliche Datenobjekte, z. B. eine Datei des 7.25 Millionen Ländernamen speicherresidente werden.

Zusätzliche System-Testergebnisse

Abbildung 5 zeigt die Testergebnisse auf einem weiteren System (Intel i7 860, 2,80 GHz, vier Kerne acht Threads Windows 7, 4 GB RAM). Der Prozessor unterstützt hyper-threading, daher sind die getesteten DoP Werte 1, 2,..., 8. Abbildung 1 basiert auf einem Testsystem mit sechs AMD Kernen;Dieses System unterstützt keine hyper-threading.

image: Intel i7 860, 2.80GHz, Four Cores, Eight Threads, Windows 7, 4GB RAM

Abbildung 5 Intel i7 860, 2,80 GHz, vier Kernen acht Threads Windows 7, 4 GB RAM

Zwei zusätzliche Testkonfigurationen, ähnliche Ergebnisse erzeugt (und die vollständigen Daten sind auf meiner Website verfügbar):

  • Intel i7 720, 1.60 GHz, vier Kerne acht Threads Windows 7, 8 GB RAM
  • Intel i3, 530 2.93 GHz, zwei Kerne vier Threads Windows XP64, 4 GB RAM

Interessante Leistungsmerkmale umfassen:

  • Geonames Threads bietet konsistent die beste Leistung, zusammen mit Geonames systemeigen .
  • Geonames Index ist die schnellste PLINQ-Lösung, die Annäherung an die Leistung von Threads Geonames . Hinweis*: Geonames* IndexFields ist etwas schneller, aber es ist nicht in derAbbildung 5dargestellt.
  • Abgesehen von Geonames Index skaliert alle PLINQ-Lösungen negativ mit der DoP für mehr als zwei DoP;Das heißt, wird die Systemleistung verringert, wie Vorgänge, erhöht sich die Anzahl der Parallel. In diesem Beispiel führt PLINQ guten Leistung nur bei Verwendung mit indizierten Objekte.
  • Der Anteil der Leistung hyper-threading ist Randmodell. Aus diesem Grund erhöhen Geonames Threads und -Leistung Geonames Index nicht deutlich für DoP größer als 4. Diese schlechte HT-Skalierbarkeit möglicherweise eine Folge der zwei Threads auf logischen Prozessoren auf die gleiche zentrale Planung, sondern um sicherzustellen, dass Sie auf unterschiedliche Kerne möglichst ausgeführt. Nicht jedoch diese Erläuterung als Mark E. plausibel werden angezeigt. Russinovich, David A. Solomon und Alex Ionescu auf sagen, dass physische Prozessoren vor logischen Prozessoren auf p geplant werden. Ihr Buch “ Windows Internals, fünfte Edition ” 40 (Microsoft Press, 2009). AMD-Systeme ohne HT ( Abbildung 1 ) bereitgestellt, etwa drei bis vier Mal die Leistung mit mehr als vier DoP, im Vergleich zu sequenziellen DoP, einem Ergebnisse für Threadsnative von und Index-. Abbildung 1 zeigt an, dass die beste Leistung bei der DoP ist identisch mit der Anzahl der zentralen wobei multithreaded Leistung 4.2 Zeiten die DoP eine Leistung auftritt.

Zusammenfassung der Ergebnisse

PLINQ bietet eine hervorragende Modell für die Verarbeitung von Datenstrukturen im Speicher, und es kann zur Verbesserung der Leistung von vorhandenen Code mit einigen einfachen Änderungen (z. B. Helper ) oder fortgeschrittenere Techniken, wie mit MMByte gezeigt wurde. Keines der einfachen Erweiterungen bieten jedoch nahe an der systemeigenen oder multithreaded C#-Leistung / .NET Code. Die Verbesserung nicht mit der Anzahl der Kern und DoP darüber hinaus skaliert werden.

PLINQ kommen schließen, systemeigene und c# / Leistung von .NET Code, aber es erfordert die Verwendung von indizierten Datenobjekte.

Verwenden den Code und Daten

Der gesamte Code steht auf meiner Website ( jmhartsoftware.com/SequentialFileProcessingSupport.html ), folgen Sie diesen Anweisungen:

  • Wechseln Sie zu der Seite, um eine ZIP-Datei mit PLINQ Code und Geonames Threads Code downloaden. Alle Varianten von PLINQ sind im Projekt GeonamesPLINQ (Visual Studio 2010;Visual Studio 2010 Express ist ausreichend). Geonames Threads ist im Projekt GeonamesThreads Visual Studio 2010. Die Projekte sind beide für 64-Bit-Version baut konfiguriert. Die ZIP-Datei enthält außerdem eine Kalkulationstabelle mit den unformatierten Leistungsdaten in Abbildung 1, 2 und 5 verwendet. Ein einfacher “ Usage ” Kommentar am Anfang der Datei wird die Befehlszeilenoption zum Auswählen der Eingabedatei, DoP und Implementierung erläutert.
  • Wechseln Sie zur Windows System-Programmierung Unterstützung Seite (jmhartsoftware.com/comments_updates.html ) Geonames systemeigen Code und Projekte (eine ZIP-Datei) downloaden, finden Sie das Projekt Geonames. Eine Datei ReadMe.txt erläutert die Struktur.
  • Downloaden Sie die Datenbank GeoNames von download.geonames.org/export/dump/allCountries.zip-.

Unexplored Fragen

In diesem Artikel verglichen, die Leistung mehrere alternative Techniken, um dasselbe Problem zu lösen. Der Ansatz wurde Standardschnittstellen verwenden, wie Sie sind, und ein einfaches shared Memory-Modell für die Prozessoren und Threads annehmen. Es wurde jedoch keine erheblichen Aufwand, die tief in die zugrunde liegende Implementierungen oder bestimmte Features der Computer Test zu untersuchen, und zahlreiche Fragen konnte in der Zukunft untersucht werden. Hier einige Beispiele:

  • Was ist die Auswirkung der Cachefehler und gibt es Methode, um die Auswirkungen zu verringern?
  • Was wäre die Auswirkungen der solid-state Datenträger?
  • Gibt es eine Möglichkeit, die Leistung Lücke zwischen der Projektmappe PLINQ IndexThreads und Lösungen für systemeigene zu verringern? Alle wichtigen Vorteil Experimente, reduzieren die Datenmenge, die in den Methoden FileMmByte IEnumerator.MoveNext und Current kopieren nicht angezeigt werden.
  • Ist die Leistung nahe an die theoretische maximale gemäß Speicherbandbreite, CPU-Geschwindigkeit und andere architektonische Features?
  • Gibt es eine Möglichkeit, skalierbare Leistung auf Systemen mit HT (siehe Abbildung 5 ) zu erhalten, die auf Systemen ohne HT ( Abbildung 1 ) vergleichbar ist?
  • Können Sie die Tools für die Profilerstellung und Visual Studio 2010 erkennen und Entfernen von Leistungsengpässen?

Ich hoffe, Sie näher untersuchen können.

Johnson (John) M. Hart is a consultant specializing in Microsoft Windows and Microsoft .NET Framework application architecture and development, technical training and writing. Er hat viele Jahre Erfahrung als Softwareentwickler, Infrastrukturtechnik und Architekt bei Cilk Arts Inc.(da von Intel Corporation erworben), Sierra Atlantic Inc., Hewlett-Packard Co.und Apollo des Computers. Er seit vielen Jahren als Computer Science Professor bedient und hat vier Editionen von “ Windows System Programming ” (Addison-Wesley, 2010) verfasst.

Dank an die folgenden technischen Experten für die Überprüfung der in diesem Artikel: Michael Bruestle, Andrew Greenwald , Edelmetall Magennis and CK Park