2009-11-02 19 views
24

Schrieb ein schnelles Java-Programm, um 10 Threads mit jeder Priorität zu erzeugen und pi (4 * atan (1) -Methode) mit jeweils 500.000 BigDecimals zu berechnen, bei jedem Thread beizutreten und die abgelaufene Zeit für die run-Methode zu melden. Ja, wahrscheinlich nicht das beste Beispiel, aber es einfach zu halten.Implementieren Linux JVMs tatsächlich Thread-Prioritäten?

Ich bin mir dessen bewusst Bug4813310

Es ist nicht trivial in C zu tun, aber wir können davon ausgehen, dass einheimische Prioritäten nie auf Linux JVMs gesetzt werden?

$uname -r && grep bogomips /proc/cpuinfo 
2.4.33.3 
bogomips  : 4312.26 
$java -version 2>&1 |head -1 
Java version "1.6.0_01" 
$javac T.java && java -Xmx32m -XX:+UseThreadPriorities T 
1:3112 
2:2636 
3:2662 
4:3118 
5:2870 
6:3319 
7:3412 
8:3304 
9:3299 
10:3069 

Sieht aus wie nicht viel von einer Abweichung, die man erwarten würde! Das war auf einer kleinen virtuellen Linux-Maschine. Vielleicht nur Suns? Wir werden versuchen, IBM J9 VM:

1:4091 
2:4142 
3:3957 
4:3905 
5:3984 
6:3985 
7:4130 
8:4055 
9:3752 
10:4071 

Die Bruttozahlen im Vergleich ziemlich gut, aber es gibt keine Skala auf die Zahlen aus einer Thread-Priorität Perspektive.

der 500k Iterationen auf einem 2.6-Kernel mit einer älteren Sun JVM, ein Lassen Sie versuchen, die ständig mit Last ist selten unter 7 geladen wird:

$uname -r && grep bogomips /proc/cpuinfo 
2.6.9-67.ELsmp 
bogomips  : 3992.93 
bogomips  : 3990.00 
$java -version 2>&1 |head -1 
java version "1.4.2_14" 
$javac T.java && java -Xmx32m -XX:+UseThreadPriorities T 
1:63200 
2:64388 
3:62532 
4:58529 
5:62292 
6:64872 
7:64885 
8:64584 
9:61653 
10:61575 

Lassen Sie uns versuchen IBM J9 auf einer realen Platte nur mit 2.6-Kernel und Seit einem größeren System werde ich Iterationen auf 2.000.000 erhöhen.

Einige großartige Zeiten, aber immer noch keine offensichtlichen Thread/Prozess Prioritäten.

Versuchen wir eine Windows-Box. Ich weiß, dass Windows ein ziemlich aggressives Thread-Prioritätsschema hat. Alles über normal anecdotaly verbraucht viel mehr. Lassen Sie uns als nächstes zu 900.000 Iterationen in jedem Thread übergehen:

C:\>java -version 
java version "1.6.0_11" 
C:\>java -Xmx32m T 
1:12578 
2:12625 
3:11469 
4:11453 
5:10781 
6:8937 
7:10516 
8:8406 
9:9953 
10:7391 

Sehr, was wir suchen, nein?

Also Linux JVM's haben anscheinend keine Thread-Priorität? Ich verstehe, dass Sie nicht wirklich auf ein niedrigeres nettes Niveau in C zurückkehren können, aber ich würde annehmen, dass die JVM-Ingenieure herausgefunden hätten, wie man einen Dispatcher mit niedrigen Zahlen hält.

Antwort

20

Nun, lassen Sie uns bei the source aussehen:

Linie 2947:

//////////////////////////////////////////////////////////////////////////////// 
// thread priority support 

// Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER 
// only supports dynamic priority, static priority must be zero. For real-time 
// applications, Linux supports SCHED_RR which allows static priority (1-99). 
// However, for large multi-threaded applications, SCHED_RR is not only slower 
// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out 
// of 5 runs - Sep 2005). 
// 
// The following code actually changes the niceness of kernel-thread/LWP. It 
// has an assumption that setpriority() only modifies one kernel-thread/LWP, 
// not the entire user process, and user level threads are 1:1 mapped to kernel 
// threads. It has always been the case, but could change in the future. For 
// this reason, the code should not be used as default (ThreadPriorityPolicy=0). 
// It is only used when ThreadPriorityPolicy=1 and requires root privilege. 

...

Linie 2982:

static int prio_init() { 
    if (ThreadPriorityPolicy == 1) { 
    // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1 
    // if effective uid is not root. Perhaps, a more elegant way of doing 
    // this is to test CAP_SYS_NICE capability, but that will require libcap.so 
    if (geteuid() != 0) { 
     if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) { 
     warning("-XX:ThreadPriorityPolicy requires root privilege on Linux"); 
     } 
     ThreadPriorityPolicy = 0; 
    } 
    } 
    return 0; 
} 

...

Linie 2997:

OSReturn os::set_native_priority(Thread* thread, int newpri) { 
    if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK; 

    int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri); 
    return (ret == 0) ? OS_OK : OS_ERR; 
} 

So! Zumindest unter Sun Java, unter Linux, sehen Sie keine Threadprioritäten, außer Sie haben -XX:ThreadPriorityPolicy getan und das scheint root zu benötigen.

+4

Ich dachte das auch. Die Umstellung auf root mit UseThreadPriorities hat nichts bewirkt. jedoch als Wurzel und '-XX: ThreadPriorityPolicy = 1' yeilds: 1: 3809 2: 3587 3: 3679 4: 3223 5: 2796 6: 2686 7: 2233 8: 1895 9: 1759 10: 2311 Sieht gut aus :) – Xailor

+0

geben -XX: ThreadPriorityPolicy Wert = 0 und = 1 werden Sie auch lassen heben ein Gewinde PRIO – Schildmeijer

0

Nur ein Schuss in die Dunkelheit hier, hätte aber keine Priorität in Threads in der JVM erfordert die Fähigkeit, die Priorität der Betriebssystem-Threads anpassen?

Linux (und ein beliebiges Unix-ähnliches Betriebssystem) schränkt die Möglichkeit ein, Prozessen root höhere Priorität zu geben. Ich würde denken, dass es eine ähnliche Beschränkung für Threads geben würde.

+0

Stimmt, Sie können sich up-up, nur nicht down. Ich würde jedoch denken, dass ein Versandthread/-prozess die 10 Ebenen UPWARDS von wo eins ist. Vielleicht hat sogar (keuchen) einen separaten Root-Daemon, der Prioritäten für JVM-Threads zuweisen würde. – Xailor

+0

Ich weiß nichts über Java, aber in .NET sind verwaltete Threads nicht mit OS-Threads identisch, d. H. Die CLR plant Threads für sich. Daher sollte dies auch für eine JVM möglich sein. – OregonGhost

+0

Ich glaube nicht, dass CLR grüne Fäden verwendet. Ich bin mir fast sicher, dass die Thread-Planung vom Betriebssystem durchgeführt wird. – jassuncao

1

Die standardmäßige Linux-Thread-Scheduler-Richtlinie SCHED_OTHER unterstützt keine Prioritäten. Genauer gesagt unterstützt es eine Prioritätseinstellung mit einem Wert: 0. Die anderen sogenannten Echtzeit-Richtlinien SCHED_FIFO und SCHED_RR unterstützen höhere Prioritäten, sind jedoch nur für Prozesse mit Super-User-Privilegien verfügbar.

+0

Was aus den anderen Code-Schnipsel bedeuten soll '! SCHED_OTHER // unterstützt nur dynamische Priorität' – Xailor

+0

SCHED_OTHER unterstützt nur Niceeness, was ein Hinweis ist der Scheduler zur Priorisierung von Threads und Prozessen. –