F #: Asynch und Aufgaben und PLINQ, oh mein!

8

Wenn F # rauskommt, werde ich im Bereich der asynchronen / parallelen Programmierung eine Schande über Reichtümer haben. Eine Antwort auf diese Frage tut Es ist ziemlich gut, die Unterschiede zwischen Tasks, Parallel LINQ und Reactive Framework zu beschreiben, aber ich habe mich gefragt, wie asynchrone Arbeitsabläufe genau in das Bild passen.

Bitte korrigieren Sie mich, wenn ich falsch liege, aber wie ich es verstehe, werden asynch-Workflows die einfachste Möglichkeit sein, mit IO-gebundenen Operationen zu arbeiten, insbesondere solchen, die eine AsynchXxx-Methode definiert haben oder dem BeginXxx / EndXxx-Muster folgen . Ein weiterer Vorteil besteht darin, dass asynch-Workflows zusammensetzbar sind und aus anderen asynch-Workflows aufgebaut werden können - was die Struktur eines Programms sehr flexibel gestalten kann.

Ich denke, ich brauche Hilfe, um zu verstehen, unter welchen Umständen ich Tasks oder PLINQ über asynchronen Workflows im F # -Code wählen würde. Ich glaube, ich habe gelesen, dass die Task Parallel Library ausgefeiltere Möglichkeiten bietet, um die Last auf die Kerne auszubalancieren. Wenn dies der Fall ist, sind Tasks möglicherweise die bessere Wahl für rein CPU-gebundene Operationen, die parallel ausgeführt werden müssen. PLINQ hingegen scheint vor allem eine bequeme Möglichkeit zu sein, vorhandenen Code, der mit Sequenzen arbeitet, zu parallelisieren.

Wenn schließlich mein Verständnis der Stärken jedes Ansatzes richtig ist, ist es dann immer möglich oder ratsam, sie zu kombinieren? Beispielsweise könnte man aus asynchronen Workflows eine Reihe von Operationen zusammenstellen und sie dann vor der Ausführung in Tasks umwandeln. Wenn das möglich ist - oder auch nur eine gute Idee.

    
Joel Mueller 01.02.2010, 17:15
quelle

2 Antworten

12

Siehe Task Parallel Library vs Async Workflows .

>

Ich würde die Grundlagen wie folgt zusammenfassen:

Task Parallel Library : Ermöglicht die effiziente Ausführung mehrerer Arbeitseinheiten auf mehreren Kernen, einschließlich relativ einfacher Szenarien, z. B. das Erstellen mehrerer Threads für parallele Berechnungen sowie kompliziertere Operationen für die Berechnungen selbst entstehen auch zusätzliche Aufgaben. Verwendet die verbesserten .NET 4.0-Threadpool- und Work-Stealing-Warteschlangen, um sicherzustellen, dass alle Kerne besetzt sind.

Async-Workflows : Ermöglicht die Ausführung asynchroner Berechnungen, ohne unnötige Threads zu belegen und Rückrufe einzuleiten, sobald Ergebnisse verfügbar sind.

PLINQ : Code, der mit PLINQ geschrieben wurde, läuft über den TPL, aber dies ist eine nettere Schnittstelle für Code, die leicht mit LINQ-Abfragen ausgedrückt werden kann (z. B. eine einzelne Operation für jedes Element in einem Array) Daten parallel).

Beachten Sie, dass asynchrone Workflows mit der Methode StartAsTask in Tasks konvertiert werden können und Tasks mit der Methode Async in Async.AwaitTask s konvertiert werden können. Daher ist es möglich, die Technologien zu überbrücken, obwohl sie nur geringfügig angestrebt werden verschiedene Zielszenarien.

Für mich wäre die Faustregel, dass Sie, wenn Sie aktiv an vielen Threads arbeiten, den TPL verwenden möchten (möglicherweise über PLINQ oder ein F # -Equivalent wie das PSeq-Modul), während Wenn Sie versuchen, viele IO (ob parallel oder nicht) zu tun, sollten Sie asynch Workflows verwenden. Ein Raytracer würde also TPL verwenden, um Aufgaben auszulösen, um jedes Pixel (oder Scanline) parallel zu rendern und die verfügbare Rechenleistung auf Ihrem Computer zu maximieren. Das Herunterladen einer Reihe von Webseiten würde jedoch mit asynchronen Workflows erfolgen, da sich nicht viel Rechenaufwand zwischen den Kernen verteilen würde. Sie müssen nur vom Betriebssystem benachrichtigt werden, wenn die Ergebnisse eingetroffen sind.

    
kvb 01.02.2010, 18:38
quelle
1

Async-Workflows werden über die monadische F # -Syntax implementiert. Das bedeutet, dass Sie Ihre Workflows nicht in eine Task transformieren müssen, sondern Ihre eigene Version von "async" schreiben können, die auf der parallelen Task-Bibliothek basiert. Ich sage das mit ein paar Vorbehalten:

  • Es wäre schwierig zu tun.
  • Async-Operationen, die das BeginXxx / EndXxx-Muster in .NET verwenden, registrieren dort Callbacks im Thread-Pool. Ich bin mir nicht sicher, dass du das ändern könntest, um stattdessen Aufgaben zu verwenden.

Weitere Einzelheiten zur Implementierung einer Monade in F # finden Sie im Buch "Expert F #" oder googeln Sie ein wenig über "F # monads".

Keine vollständige Antwort, aber ich hoffe, es hilft ein bisschen.

    
Robert 01.02.2010 17:42
quelle

Tags und Links