2016-08-07 37 views
0

ich für eine Bewertung über diese Frage vor kurzem kam:Wie groß sollte der Thread-Pool sein, um maximale Leistung zu erzielen?

ExecutorService threadpool = Executors.newFixedThreadPool(N); 

for(Runnable task : tasks){ 
    threadpool.submit(task); 
} 

Jede Aufgabe verbringt 25% für die Berechnung und 75% tun I/O. Angenommen, wir arbeiten an einer Quad-Core-Maschine (kein Hyper-Threading). Wie groß sollte Thread-Pool-N sein, um maximale Leistung zu erzielen, ohne Threads zu verschwenden? (Nehmen wir an, wir haben unendliche I/O-Kapazität)

Ich schätzte 16, da die Maschine unendliche I/O hat bedeutet, dass wir uns voll auf CPUs konzentrieren können. Jede Task verwendet während des Betriebs ein Viertel der CPU. Das heißt, wir können vier Tasks ausführen, um einen CPU-Kern zu sättigen, und das macht N = 16 auf einem Quad-Core-Rechner.

Update: Die Optionen für diese Fragen waren 2,4,5,6,7,8,12 und 16.

+3

Was ist deine Antwort, wie bist du darauf gekommen, und warum denkst du nicht, dass es die richtige Antwort ist? – Andreas

+0

meine antwort war 16, da die maschine unendliche e/a hat, bedeutet das, dass wir uns voll auf die CPUs konzentrieren können. Jede Task verwendet während des Betriebs ein Viertel der CPU. Das heißt, wir können vier Tasks ausführen, um einen CPU-Kern zu sättigen, und das macht N = 16 auf einem Quad-Core-Rechner. – Mickey

+0

Klingt wie die richtige Antwort auf mich. – Andreas

Antwort

0

Sie sind richtig, dass Sie sättigen Ihre Kerne denken sollte. Die beste Antwort wird jedoch mehr als 16 sein. Wenn Sie nur 16 Threads haben, werden die CPU-Anforderungen nicht perfekt aufeinander abgestimmt, so dass alle Ihre Kerne die ganze Zeit verwendet werden.

Die beste Antwort ist also> 16, aber auch klein genug, um die Zeit für die Fertigstellung einzelner Tasks nicht wesentlich zu erhöhen, die Kosten für die Thread-Umschaltung zu erhöhen oder viel Speicher zu verschwenden.

Wenn Sie das in der Klasse gelernt haben, dann hat Ihnen Ihr Prof wahrscheinlich einen Multiplikator als "Faustregel" gegeben. Er würde erwarten, dass Sie sich daran erinnern und es hier anwenden.

Normalerweise verwende ich average_demand = 2 * num_cores, würde also 32 Threads auswählen. Dies funktioniert in den meisten Fällen gut. Wenn die durchschnittliche CPU-Nachfrage doppelt so hoch ist wie die Anzahl der Kerne, liegt die Kernauslastung bei nahezu 100%.

Auch in diesem Fall erhält der CPU-Teil jeder Aufgabe nur 1/2 Kern im Durchschnitt, so dass es doppelt so lange dauert ... aber es ist nur 25% der Arbeit, so dass die Task-Abschlusszeit nur 13 ist % mehr als optimal.

Der 2-fache Standardwert, den ich verwende, ist fast immer höher als die optimale Anzahl, aber auch fast immer niedrig genug, um keinen zusätzlichen Overhead zu verursachen. Wenn Sie wissen, dass Ihre Aufgaben sehr stark an die CPU gebunden sind, können Sie diese Zahl sicher reduzieren.

Wenn Sie wirklich den optimalen Wert finden möchten, dann können Sie es messen, aber wenn Sie im richtigen Bereich sind, wird es keinen großen Unterschied machen.

-

P.S HINWEIS: Der ‚average_demand‘ I verwenden oben ist die erwartete Anzahl von Kernen, die bei der Verwendung jederzeit gegeben N Fäden und N-Kern sein würden.

1

Obwohl diese Frage nicht genau richtige oder falsche Antwort hat, würde das subjektiv gute sein:

32 Themen

Sie haben in Bezug auf die Wahrscheinlichkeit zu denken. Für jetzt betrachten wir nur einen CPU-Kern und unabhängige Threads:

Ein Thread hat eine 25% Chance, eine Berechnung zu einem bestimmten Zeitpunkt zu tun. Wenn Sie 2 unabhängige Threads (Wahrscheinlichkeitsereignisse) haben, ist die Wahrscheinlichkeit, dass mindestens eine CPU-Arbeit ausgeführt wird, nicht 50%, sondern 7/16 (43.75%).(Wenn Sie sich nicht sicher sind, sollten Sie einige davon aktualisieren probability skills).

Sie sehen wahrscheinlich, wohin das geht. Damit das P 100% ist, müsste die Anzahl der Threads unendlich sein. Wir müssen also eine fundierte Schätzung machen: 4 Gewinde haben ein P von ~ 68%, 8 Gewinde ~ 90%. Es wäre jetzt wirklich unproduktiv, in die Zählung zu gehen, also setzen wir uns mit 8 fort. Das ist für einen Kern. Wir haben 4 CPU-Kerne, also können wir das mit 4 multiplizieren und wir bekommen die endgültige Antwort: 32.