24

クイックJavaプログラムを作成して、各優先度で10個のスレッドを生成し、BigDecimalsでそれぞれ500,000回pi(4 * atan(1)メソッド)を計算し、各スレッドに参加して、runメソッドの経過時間を報告します。ええ、おそらく最良の例ではありませんが、それを基本的に保ちます。

Bug4813310を知っています

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マシン上にありました。たぶんSunだけ?IBMJ9VMを試してみましょう。

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

総計は比較するとかなり見栄えがしますが、スレッドの優先順位の観点からは数値にスケールはありません。

古いSunJVMを使用して2.6カーネルで500kの反復を試してみましょう。これは、負荷平均が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

2.6カーネルだけを使用した実際のスラブでIBMのJ9を試してみましょう。システムが大きいため、反復回数を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ボックスを試してみましょう。私は、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エンジニアは、ある種の低品質のディスパッチャーを維持する方法を理解していると思います。

4

3 に答える 3

22

JDK 8のソースコードから、コメントは次のようになります。

////////////////////////////////////////////////////////////////////////////////
// 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.

..。

後で、次のようになります。

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;
    }
  }

  if (UseCriticalJavaThreadPriority) {
    os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
  }

  return 0;
}

..。

そして続いて

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;
}

それで!少なくともSunJava、Linuxでは、スレッドの優先順位を確認しない限り、スレッドの優先順位は表示されません-XX:ThreadPriorityPolicy。これにはrootが必要と思われます。

于 2009-11-02T17:21:31.523 に答える
1

ここでは暗闇の中でのショットですが、JVMで優先順位付けされたスレッドを使用するには、オペレーティングシステムスレッドの優先順位を調整する機能が必要ではないでしょうか。

Linux(およびUnixライクなOS)は、プロセスにrootより高い優先順位を与える機能を制限します。スレッドにも同様の制限があると思います。

于 2009-11-02T16:29:53.203 に答える
1

デフォルトのLinuxスレッドスケジューラポリシーSCHED_OTHERは、優先度をサポートしていません。または、より正確には、1つの値0の優先順位設定をサポートします。もう1つのいわゆる「リアルタイム」ポリシーSCHED_FIFOおよびSCHED_RRは、より高い優先順位をサポートしますが、スーパーユーザー特権を持つプロセスでのみ使用できます。

于 2009-11-02T17:25:37.257 に答える