2009-11-02 13 views
24

Escribí un rápido programa de Java para generar 10 hilos con cada prioridad y calculo el método pi (4 * atan (1)) con BigDecimals 500,000 veces cada uno, únete a cada hilo e informa el tiempo transcurrido para el método de ejecución. Sí, probablemente no sea el mejor ejemplo, pero mantenerlo básico.¿Las JVM de Linux realmente implementan las prioridades de subprocesos?

Soy consciente de Bug4813310

Es no trivial que hacer en C, pero podemos suponer que las prioridades de cacao nunca se fijan en las JVM Linux?

$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 

Parece una desviación no muy esperada. Eso fue en una pequeña máquina virtual de Linux. Tal vez solo Sun's? Trataremos de IBM J9 VM:

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

Los números brutos se ven bastante bien en comparación, pero no existe una escala a los números desde una perspectiva prioridad hilo.

Probemos 500 k iteraciones en un kernel 2.6 con una mayor JVM de Sun, uno que está constantemente cargado con carga media rara vez por debajo de 7:

$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 

Probemos J9 de IBM en una losa verdadera simplemente con el kernel 2.6 y dado que un sistema más grande aumentaré las iteraciones a 2,000,000.

$uname -r && grep bogomips /proc/cpuinfo 
2.6.9-78.ELsmp 
bogomips  : 5989.03 
bogomips  : 5985.03 
bogomips  : 5985.01 
bogomips  : 5985.02 
bogomips  : 5984.99 
bogomips  : 5985.02 
bogomips  : 5984.99 
bogomips  : 5985.02 
$java -Xmx32m T # this is the IBM J9 
1:1718 
2:1569 
3:1989 
4:1897 
5:1839 
6:1688 
7:1634 
8:1552 
9:2027 
10:1522 

Algunos buenos momentos, pero todavía no aparentan determinar el hilo/las prioridades del proceso.

Probemos un cuadro de Windows. Sé que Windows tiene un esquema de prioridades de subprocesos bastante agresivo. Cualquier cosa por encima de normal anecdotario consume mucho más. Como tal, pasemos a 900,000 iteraciones en cada hilo:

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 

Mucho de lo que estamos buscando, ¿no?

¿Parece que las JVM de Linux no tienen prioridad de subprocesos? Entiendo que no se puede realmente renice a un nivel más bajo en C, pero supongo que los ingenieros de JVM habrán descubierto cómo mantener a un despachador de poca monta.

Respuesta

20

Bueno, vamos a ver the source:

línea 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. 

...

línea 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; 
} 

...

línea 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; 
} 

Así! Al menos en Sun Java, en Linux, no verá las prioridades de subprocesos a menos que haya hecho -XX:ThreadPriorityPolicy y que, al parecer, requiera root.

+4

Yo también pensé eso. Cambiar a root con UseThreadPriorities no afectó nada. Sin embargo, como la raíz y '-XX: ThreadPriorityPolicy = 1' yeilds: 1: 3809 2: 3587 3: 3679 4: 3223 5: 2796 6: 2686 7: 2233 8: 1895 9: 1759 10: 2311 Verse bien :) – Xailor

+0

dar -XX: ThreadPriorityPolicy un valor = 0 y = 1 también le permitirá levantar una hilos PRIO – Schildmeijer

0

¿Solo un tiro en la oscuridad aquí, pero no tener subprocesos priorizados en la JVM requiere tener la capacidad de ajustar la prioridad de los hilos del sistema operativo?

Linux (y cualquier sistema operativo tipo Unix) limita la capacidad de dar a los procesos una mayor prioridad a la raíz. Creo que habría una limitación similar en los hilos.

+0

Es cierto, puede renunciar UP, simplemente no hacia abajo. Sin embargo, creo que un hilo/proceso de despacho podría renizar los 10 niveles UPWARDS de donde se encuentra uno. Quizás incluso (gasp) tenga un daemon raíz separado que asignaría prioridades para los hilos JVM. – Xailor

+0

No sé acerca de Java, pero en .NET, los hilos gestionados no son lo mismo que los hilos del sistema operativo, es decir, el CLR planifica los hilos por sí mismo. Por lo tanto, esto también debería ser posible para una JVM. – OregonGhost

+0

No creo que CLR use hilos verdes. Estoy casi seguro de que la programación de hilos la realiza el SO. – jassuncao

1

La política predeterminada del programador de hilos de Linux SCHED_OTHER no admite prioridades. O para ser más exactos, admite una configuración de prioridad con un valor: 0. Las otras políticas denominadas de "tiempo real" SCHED_FIFO y SCHED_RR admiten prioridades más altas, pero solo están disponibles para procesos con privilegios de superusuario.

+0

que es esto supone que significa desde el otro fragmento de código '! SCHED_OTHER // solo admite la prioridad dinámica' – Xailor

+0

SCHED_OTHER solo es compatible con la amabilidad, que es una pista para el programador sobre cómo priorizar hilos y procesos. –

Cuestiones relacionadas