Effizienz von Windows Threads



  • Hi,

    ich nutze momentan für Aufgaben, die quasi-parallel abgearbeitet werden sollen (aber auch möglicherweise vorhandene weitere Prozessorkerne benutzen sollen) die Standard Windows Threads.

    Jetzt laufen einige dieser Threads allerdings nur für eine sehr kurze Zeit, so dass ich mich frage, wie effizient das im Vergleich zu dem Overhead ist, der beim Erzeugen und Entfernen des Threads anfällt. Oder anders gefragt: gibt es irgend eine Faustregel, ab wann Threads sich lohnen, z.B. eine Angabe, ab welcher Thread-Lebensdauer das der Fall ist?

    Meccc

    PS: Eine ähnliche Frage habe ich auch im Linux-forum gestellt, das ist jedoch KEIN Doppelpost, da es dort um den Posix-Threadmechanismus geht und ich in meiner Applikation - je nach Plattform - beide verwende



  • Für viele kurze Threads würde ich Thread-Pools benutzen. Damit hast Du nicht notwendigerweise den Overhead des Anlegens/Entfernens des Threads. Das kann ganz einfach gehen, sie z.B. QueueUserWorkItem.



  • ACK

    Thread Pools sind gut, und das "übergeben" eines Work-Items an einen Worker-Thread/Thread-Pool ist wesentlich billiger, als das Anlegen eines neuen Threads.

    Das gilt sowohl für Windows als auch für PTHREADS.

    Und Threads die schlafen sind - zumindest auf Windows - ziemlich billig. Kannst du gerne 100 Threads haben die rumgammeln und nie Arbeit bekommen, solange du ihnen keine Arbeit gibst, kosten die auch so-gut-wie keine Rechenzeit.



  • hustbaer schrieb:

    Das gilt sowohl für Windows als auch für PTHREADS.

    Das überrascht mich jetzt aber! Ich habe zwischenzeitlich mal folgenden Test (mit PThreads) gemacht:

    1. Eine Applikation, die nichts weiter macht, als einen Thread zu erzeugen, darauf zu warten, das der wieder beendet wird (der Thread selber macht nichts weiter als eine einzelne Variable zu setzen) um dann den Vorgang zu wiederholen. Das Ganze dann ein paar zigtausend mal.

    2. Einen Thread einmalig erzeugen und den innerhalb einer Schleife auf ein externes Event per Conditional Variable Warten lassen: ist dieser Event aufgetreten, wird eine Funktion per Funktionspointer aufgerufen, die eine einzelne Variable setzt. Anschließend legt der Thread sich wieder schlafen und wartet auf den nächsten Event. Hier wurden die Events immer geschickt, so bald der Thread schlafen gegangen ist.

    Das überraschende Ergebnis: Variante 2 (die im Wesentlichen so einem Threadpool entspricht) war um ein Vielfaches langsamer. Ich vermute hier, dass das ganze Mutex/CondVar-Handling deutlich mehr Zeit benötigt, als das Anlegen eines neuen Threads.



  • Mal ein ganz anderer Ansatz:
    Hast Du Dir mal die Fibers näher angeschaut?

    Ich denke, sie sollen noch schlanker sein als die Threads.
    Allerdings muß ich hier zugeben, daß ich sowas noch nie real ausprobiert habe.

    Jedenfalls habe ich mir zu diesem Thema eine Linkliste zusammengestellt, falls ich irgendwann mal auf Fibers zurückgreifen soll.
    Hier einige für den Start:
    "COUNTER project" (Microsoft Systems Journal November 1996) http://www.microsoft.com/msj/archive/S20E4.aspx
    "A Fiber Class (and Friends)" http://www.codeproject.com/KB/threads/fibers.aspx

    just my 5 cents,
    Martin



  • ThreadPools sind auf jeden Fall vorzuziehen. Vermutlich ist an Deinem Test etwas Faul.

    Mit Fibers sollte man nur arbeiten, wenn man weiss was man tut!

    Mit VS2010 gibt es ja das PPL (Paralell Pattern Library), die sogar noch besser als "normale" ThreadPools sind...
    http://channel9.msdn.com/pdc2008/TL25/


Anmelden zum Antworten