Hilft die "Async.Parallel" -Konstruktion wirklich, um Berechnungen auf einem Multicore-System schneller zu machen? Sind .NET TPL "Aufgaben" hier irgendwie beteiligt?
%Vor%Ich nehme an, einige von Ihnen werden es theoretisch erklären, aber ich würde auch einige echte Welttests schätzen.
Die Verwendung von F # async
für rein CPU-gebundene Aufgaben funktioniert nur, wenn die Aufgaben etwas komplizierter ausgeführt werden. Wenn Sie versuchen, Code zu paralisieren, der etwas sehr Einfaches tut, dann ist es besser, PLINQ (und die Task Parallel Library) zu verwenden, die für diese Art von Problemen besser geeignet sind.
Aber selbst dann ist es schwierig, in einem trivialen Fall wie dem, was Sie haben, zu beschleunigen. Wenn Sie etwas mehr experimentieren möchten, können Sie dies versuchen:
%Vor% Beachten Sie, dass die Verwendung von Array.map
selbst viel schneller ist als die Verwendung von Sequenzausdrücken und dann das Konvertieren des Ergebnisses in ein Array. Wenn Sie komplexere Operationen als das Mapping verwenden möchten, enthält F # PowerPack das Modul PSeq
mit ähnlichen Funktionen wie in Seq
oder List
:
Wenn du mehr darüber lesen willst, habe ich eine Blog-Serie über parallele Programmierung in F # Kürzlich.
Was pmap
macht, ist das Erstellen einer Liste von 300.000 Aufgabenobjekten, die dafür sorgen, dass sie parallel ausgeführt werden, und nur dann, wenn sie parallel ausgeführt werden. Mit anderen Worten, ein einzelner Thread wird dort sitzen und 300.000 Objekte erzeugen und sie in den Thread-Pool einreihen. Nur dann werden sie ausgeführt.
Da Ihre Aufgabe so trivial ist (eine Multiplikation und eine Division), ist der Aufwand für das Erstellen der Aufgabe, das Planen und Behandeln ihres Ergebnisses mehr als nur das Ausführen der Berechnung. Dies bedeutet, dass die Metapher async
für diese Operation ungeeignet ist. Es ist viel besser, PLINQ dafür zu verwenden.
Bei Berechnungen ist es einfacher, nur ein paar asynchrone Threads zu erstellen (wahrscheinlich einen für jede CPU), und dann berechnet jeder einen Teil Ihrer Antwort. Wie Gabe antwortete, verbringst du die meiste Zeit damit, Aufgabenobjekte zu erstellen.
Wenn ich diese Art von Plan verwende, bekomme ich Beschleunigungen, die ziemlich genau der Anzahl der CPUs entsprechen (die meisten, die ich ausprobiert habe, sind 8 ... Ich weiß, dass es nicht für immer skalieren wird)
Ein Dienstprogramm dafür zu schreiben ist mehr Arbeit als PLINQ aufzurufen, aber wenn Sie ein pmap
-Typ-Dienstprogramm haben, können Sie es einfach wiederverwenden.
Tags und Links f# parallel-processing