Реализуют ли виртуальные машины Linux приоритеты потоков? - PullRequest
24 голосов
/ 02 ноября 2009

Написал быструю Java-прогу, чтобы породить 10 потоков с каждым приоритетом и вычислить число pi (4 * atan (1)) с BigDecimals 500 000 раз каждый, присоединиться к каждому потоку и сообщить истекшее время для метода run. Да, возможно, это не лучший пример, но он остается базовым.

Мне известно о Ошибка 4813310

Это не тривиально в C, но можем ли мы предположить, что собственные приоритеты никогда не устанавливаются в Linux JVM?

$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

Похоже, не так много отклонений, которые можно было бы ожидать! Это было на маленькой виртуальной машине Linux. Может только у Солнца? Мы попробуем IBM J9 VM:

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

Значения брутто выглядят довольно неплохо по сравнению, но нет шкалы для чисел с точки зрения приоритета потока.

Давайте попробуем 500 000 итераций на ядре 2.6 с более старой Sun JVM, которая постоянно загружена средними значениями загрузки редко ниже 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

Давайте попробуем J9 IBM на реальной плите только с ядром 2.6, а с более крупной системой я увеличу количество итераций до 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

Некоторые замечательные времена, но все еще нет очевидных приоритетов потоков / процессов.

Давайте попробуем Windows box. Я знаю, что в Windows довольно агрессивная схема приоритетов потоков. Все, что выше нормальное анекдоталия, потребляет намного больше. Поэтому давайте перейдем к 900 000 итераций в каждом потоке:

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

Очень много, что мы ищем, нет?

Значит, у Linux JVM, по-видимому, нет приоритета потоков? Я понимаю, что вы не можете реально получить более низкий приятный уровень в C, но я бы предположил, что инженеры JVM разобрались бы, как сохранить неаккуратный диспетчер сортов.

Ответы [ 3 ]

20 голосов
/ 02 ноября 2009

Хорошо, давайте посмотрим на источник :

строка 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.

...

строка 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;
 }

...

строка 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;
}

Так! По крайней мере, в Sun Java, в Linux вы не увидите приоритеты потоков, если вы не выполнили -XX:ThreadPriorityPolicy, а для этого требуется root.

1 голос
/ 02 ноября 2009

Политика планировщика потоков Linux по умолчанию SCHED_OTHER не поддерживает приоритеты. Или, если быть более точным, он поддерживает настройку приоритета с одним значением: 0. Другие так называемые политики «реального времени» SCHED_FIFO и SCHED_RR поддерживают более высокие приоритеты, но доступны только процессам с привилегиями суперпользователя.

0 голосов
/ 02 ноября 2009

Здесь просто выстрел в темноте, но разве для приоритезации потоков в JVM не требуется возможность настраивать приоритет потоков операционной системы?

Linux (и любая Unix-подобная ОС) ограничивает возможность придавать процессам более высокий приоритет для root. Я думаю, что будет подобное ограничение для потоков.

...