none
Thread - Verteilung auf Prozessoren RRS feed

  • Frage

  • Guten Abend,

    wenn ich mit der Thread-Klasse arbeite, dann arbeitet jeder Thread (wenn es keine Synchronisierung gibt) für sich alleine.

    Wenn ich nun einen 8-Kern-Prozessor habe und 8 Thread erstelle, werden diese dann Automatisch auf die Prozessorkerne aufgeteilt?

    Wenn dies nicht so ist, gibt es dann eine Möglichkeit diese Thread aufzuteilen? Für die Process-Klasse gibt es zum Beispiel die Eigenschaft Process.ProcessorAffinity.

    Gibt es so etwas auch für Threads?

    Thomas Roskop

    Frohe Weihnachten wünsche ich allen!


    © 2015 Thomas Roskop

    Montag, 22. Dezember 2014 20:14

Antworten

  • Hallo,
    die Verteilung der Threads wird letzten Endes von Windows verwaltet. Du kannst bei Threads über die Priority-Eigenschaft angeben, mit welcher Priorität Windows diesen Thread arbeiten lassen soll.
    Höher priorisierte Threads erhalten mehr Zeitscheiben von Windows, wodurch sie häufiger aufgerufen werden und somit schneller sind.
    Du musst auch beachten, das es mehrere Prozesse gibt, die immer laufen oder zumindest laufen könnten. Das heißt, dass du nie die gesamte Leistung des Systems bekommen wirst. Beispielsweise laufen bei mir gerade 2252 Threads in 126 Prozessen. Alle wollen irgend wann mal Rechenzeit haben, sodass du zumindest ein wenig davon abschreiben musst.
    Windows wird die Ausführung ggf. umverteilen, wenn ein Thread deutlich mehr Leistung benötigt.

    Für kleine Aufgaben lohnt es sich weiterhin den Threadpool zu verwenden. Das spart weitere Leistung beim Windows-Seitigen Verwalten. Genauso werden Zeitgeber (Timer) effektiviert, sodass es sich mehr lohnt die vorgefertigten Klassen zu verwenden.

    Diese Effektivierungen sind mittlerweile so gut implementiert, das es IMHO eigentlich keinen Sinn mehr macht es selbst steuern zu wollen (solange man natürlich weiß wofür sich Threads lohnen usw.).
    Ein kurzer Test mit 1/2/4/8/... Threads und Leistungsfressenden Dummy-Aufgaben sollte das übrigens auch zeigen.

    PS: Dir (und den anderen Lesern) auch frohe Weihnachten!


    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thomas Roskop Dienstag, 23. Dezember 2014 06:18
    Montag, 22. Dezember 2014 21:11
    Moderator
  • Hallo zusammen,

    grundsätzlich kann man die Thread Affinität festlegen via SetThreadAffinityMask (Interop Signatur in den Kommentaren). Die Eigenschaft Process.ProcessAffinity tut gleiches für den Prozess via SetProcessAffinityMask. Wobei man einen Prozess in diesem Kontext als eine Ansammlung von Threads ansehen muss, denn mindestens einen Faden hat jedes Programm.

    Aber Tom hat schon recht, im allgemeinen sollte man davon die Finger lassen. Der Windows Scheduler ist i. a. recht gut darin, die aktiven Threads auf alle vorhandenen Kerne zu verteilen. (Die Thread Priorität ist dabei das Äquivalent zur Prozess Priorität und beeinflusst die Zuteilung durch den Scheduler).

    Jegliche "Optimierung" setzt genaues Wissen über die Prozessor-Plattform voraus. Die heutige Prozessoren arbeiten jeder Menge Tricks - z. B. Intels "Turbo-Boost", der Kerne stilllegt, um die Leistung der anderen zu erhöhen. Bei Smartphones (ARM) verwendet man unterschiedliche Kerne, um den Stromverbrauch zu senken. Auch weitere Faktoren wie NUMA spielen dabei eine Rolle. "Spielt" man mit den Thread-Affinitäten herum, kann das negative Auswirkungen auf die Gesamtleistung haben. Somit gibt es nur wenigen Ausnahmen, wo sich das lohnt -  wie beim SQL Server, der einen User Mode Scheduler verwendet - nur existieren genaue Kenntnisse über den aktuellen Arbeitssatz.

    Bezüglich .NET vs. Mono: Das Ganze hat nur wenig mit dem .NET Framework zu tun. Das Verwalten von Prozessen und Threads ist eine primäre Aufgabe des verwendeten Betriebssystems. Und Linux ist in dem Bereich nicht schlechter als Windows - einige behaupten sogar es ist besser. Was aber erst im sog. High Performance Computing wichtig wird - und .NET hat in dem Bereich ohnehin keine Aktien. Da Microsoft die Zusammenarbeit mit Xamarin intensiviert hat und der .NET Core offengelegt wird, kann man langfristig davon ausgehen, dass Windows .NET und Mono sich (in allen Bereichen) im Verhalten annähern werden.

    Gruß Elmar

    • Als Antwort markiert Thomas Roskop Dienstag, 23. Dezember 2014 06:18
    Dienstag, 23. Dezember 2014 04:37
    Beantworter

Alle Antworten

  • Hallo,
    die Verteilung der Threads wird letzten Endes von Windows verwaltet. Du kannst bei Threads über die Priority-Eigenschaft angeben, mit welcher Priorität Windows diesen Thread arbeiten lassen soll.
    Höher priorisierte Threads erhalten mehr Zeitscheiben von Windows, wodurch sie häufiger aufgerufen werden und somit schneller sind.
    Du musst auch beachten, das es mehrere Prozesse gibt, die immer laufen oder zumindest laufen könnten. Das heißt, dass du nie die gesamte Leistung des Systems bekommen wirst. Beispielsweise laufen bei mir gerade 2252 Threads in 126 Prozessen. Alle wollen irgend wann mal Rechenzeit haben, sodass du zumindest ein wenig davon abschreiben musst.
    Windows wird die Ausführung ggf. umverteilen, wenn ein Thread deutlich mehr Leistung benötigt.

    Für kleine Aufgaben lohnt es sich weiterhin den Threadpool zu verwenden. Das spart weitere Leistung beim Windows-Seitigen Verwalten. Genauso werden Zeitgeber (Timer) effektiviert, sodass es sich mehr lohnt die vorgefertigten Klassen zu verwenden.

    Diese Effektivierungen sind mittlerweile so gut implementiert, das es IMHO eigentlich keinen Sinn mehr macht es selbst steuern zu wollen (solange man natürlich weiß wofür sich Threads lohnen usw.).
    Ein kurzer Test mit 1/2/4/8/... Threads und Leistungsfressenden Dummy-Aufgaben sollte das übrigens auch zeigen.

    PS: Dir (und den anderen Lesern) auch frohe Weihnachten!


    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Thomas Roskop Dienstag, 23. Dezember 2014 06:18
    Montag, 22. Dezember 2014 21:11
    Moderator
  • Danke für die Antwort.

    Ist schade, dass man über c# die Threads nicht direkter Beeinflussen kann.

    Denn dies wäre mir wichtig.

    Allerdings glaube ich schon, dass meine Anwendung genug Leistung bekommen wird, denn das soll eine Server-Anwendung werden. Also, leeren Server nehmen, minimales Linux ohne UI installieren und dann die MonoRuntime drauf klatschen. Leider ist Windows für Server nicht so zu gebrauchen wie als normales Betriebssystem.

    Alleine nur schon das mit den Updates -> bitte noch eine halbe Stunde warten....

    Trotzdem Danke für den Einblick in c# Threads. Es war mir eigentlich recht wichtig, dass jeder Thread genau zu einem Kern geordnet wird, weil dann eine einfache Verteilung zwischen den Datenbankaufgaben möglich wäre.

    Danke.


    © 2015 Thomas Roskop

    Montag, 22. Dezember 2014 21:29
  • In Sachen Mono habe ich mich noch gar nicht mit Threading beschäftigt. Grundsätzlich ist es eine vollkommen eigene Runtime, sodass es sich da theoretisch anders verhalten kann. Aber da kenne ich mich zu wenig aus, um definitive Aussagen treffen zu können.
    Vielleicht hast du dort die Chance systemeigene APIs aufzurufen um die Threads irgendwie gleichmäßiger zu verteilen. Vielleicht läuft es aber auch so gut wie unter Windows sodass das nicht nötig ist.

    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Montag, 22. Dezember 2014 23:13
    Moderator
  • Hallo zusammen,

    grundsätzlich kann man die Thread Affinität festlegen via SetThreadAffinityMask (Interop Signatur in den Kommentaren). Die Eigenschaft Process.ProcessAffinity tut gleiches für den Prozess via SetProcessAffinityMask. Wobei man einen Prozess in diesem Kontext als eine Ansammlung von Threads ansehen muss, denn mindestens einen Faden hat jedes Programm.

    Aber Tom hat schon recht, im allgemeinen sollte man davon die Finger lassen. Der Windows Scheduler ist i. a. recht gut darin, die aktiven Threads auf alle vorhandenen Kerne zu verteilen. (Die Thread Priorität ist dabei das Äquivalent zur Prozess Priorität und beeinflusst die Zuteilung durch den Scheduler).

    Jegliche "Optimierung" setzt genaues Wissen über die Prozessor-Plattform voraus. Die heutige Prozessoren arbeiten jeder Menge Tricks - z. B. Intels "Turbo-Boost", der Kerne stilllegt, um die Leistung der anderen zu erhöhen. Bei Smartphones (ARM) verwendet man unterschiedliche Kerne, um den Stromverbrauch zu senken. Auch weitere Faktoren wie NUMA spielen dabei eine Rolle. "Spielt" man mit den Thread-Affinitäten herum, kann das negative Auswirkungen auf die Gesamtleistung haben. Somit gibt es nur wenigen Ausnahmen, wo sich das lohnt -  wie beim SQL Server, der einen User Mode Scheduler verwendet - nur existieren genaue Kenntnisse über den aktuellen Arbeitssatz.

    Bezüglich .NET vs. Mono: Das Ganze hat nur wenig mit dem .NET Framework zu tun. Das Verwalten von Prozessen und Threads ist eine primäre Aufgabe des verwendeten Betriebssystems. Und Linux ist in dem Bereich nicht schlechter als Windows - einige behaupten sogar es ist besser. Was aber erst im sog. High Performance Computing wichtig wird - und .NET hat in dem Bereich ohnehin keine Aktien. Da Microsoft die Zusammenarbeit mit Xamarin intensiviert hat und der .NET Core offengelegt wird, kann man langfristig davon ausgehen, dass Windows .NET und Mono sich (in allen Bereichen) im Verhalten annähern werden.

    Gruß Elmar

    • Als Antwort markiert Thomas Roskop Dienstag, 23. Dezember 2014 06:18
    Dienstag, 23. Dezember 2014 04:37
    Beantworter
  • Danke für die Antworten.

    Und das die entwicklung von Mono so gut fortschreitet freut mich sehr, denn ich bin schon ein großer c# Und Linux Fan. Und da es auf Linux standartmäßig nichts equivalent gutes gibt und c++ für viele Sachen zu übermäßig wäre, ist es Toll Mono verwenden zu können, unter den selben Bedinugen wie .NET - Gratis.


    © 2015 Thomas Roskop

    Dienstag, 23. Dezember 2014 06:21