Bitcoin の自動 renice
こんにちは、他のタスクに干渉しないように nice レベル 20 でビットコインを実行している。しかし時折、nice レベルが 2、あるいは 0 に自動調整されるようだ。これは仕様なのか?率直に言って、このような動作は Linux アプリケーションとしてはあるべきではない……控えめに言っても奇妙だ。
各スレッドに異なる優先度を設定している。生成スレッドは PRIO_MIN で実行される。他のスレッドは CPU をほとんど使用せず、通常の優先度で実行される。
#define THREAD_PRIORITY_LOWEST PRIO_MIN #define THREAD_PRIORITY_BELOW_NORMAL 2 #define THREAD_PRIORITY_NORMAL 0
Windows の優先度から変換された優先度は、おそらく以下のようなテーブルに基づいている:
「以下のテーブルは nice 値と Win32 優先度の対応を示しています。Win32 の優先度に関する詳細は SetThreadPriority()の Win32 ドキュメントを参照してください。
nice 値 Win32 優先度 -20 to -16 THREAD_PRIORITY_HIGHEST -15 to -6 THREAD_PRIORITY_ABOVE_NORMAL -5 to +4 THREAD_PRIORITY_NORMAL +5 to +14 THREAD_PRIORITY_BELOW_NORMAL +15 to +19 THREAD_PRIORITY_LOWEST」
より良い値があれば、提案を歓迎する。
また、Linux ではスレッドがプロセスであるためにプロセスに使用される PRIO_PROCESS についてのウェブ上のアドバイスがあった。それが正しくない場合、アプリ全体の優先度を予期せず設定してしまっている原因かもしれない。
// Linux ではスレッドはプロセスなので、PRIO_PROCESS は 1 つのスレッドだけに影響する
setpriority(PRIO_PROCESS, getpid(), nPriority); こんにちは。
同じ挙動には自分も悩まされていた。bitcoind が優先度を取ってしまってシステムの応答性が落ちていたので、全スレッドを 19 に renice していたのだが、時々プログラムが自動的に優先度をシステムの応答性を損なう値に戻してしまっていた…… そこで自分がやったのは、util.h を編集して、優先度を操作する関数をこう書き換えただけだ:
inline void SetThreadPriority(int nPriority) { printf(“No, were not changing any damn priority\n”); }
そして bitcoind を再コンパイルした。
今は最初に全スレッドを一度 renice するだけで、プログラム終了までその値で固定されたままになる(NI 列は 19 のまま):
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%] Time: 03:59:40
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%] Uptime: 253 days(!), 01:12:27
Mem[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||501/1255MB] Load: 4.01
Swp[|||||||||||||||||||||||||||||||||||||||||||||||||||||| 501/1004MB] Load average: 4.01 4.15 3.49
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
| | |__ __| |__ |__||__ |__| | | | | | | | | | | | | __| __| | |
Avg: |__|.|__|% sy: |__ . __|% ni: __||__|.|__|% hi: |__|.|__|% si: |__|.|__|% wa: |__|.|__|% Tasks: __| __| | total, | running
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
4523 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.66 `- bitcoind -gen -daemon
4534 root 39 19 126M 46280 3424 R 90.0 3.6 12:43.73 | `- bitcoind -gen -daemon
4533 root 39 19 126M 46280 3424 R 45.0 3.6 10:49.02 | `- bitcoind -gen -daemon
4532 root 39 19 126M 46280 3424 R 46.0 3.6 10:05.83 | `- bitcoind -gen -daemon
4531 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.03 | `- bitcoind -gen -daemon
4530 root 39 19 126M 46280 3424 S 1.0 3.6 0:15.53 | `- bitcoind -gen -daemon
4529 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.72 | `- bitcoind -gen -daemon
4527 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.02 | `- bitcoind -gen -daemon
4526 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.03 | `- bitcoind -gen -daemon
4525 root 39 19 126M 46280 3424 S 0.0 3.6 0:00.06 | `- bitcoind -gen -daemon
debug.logにはこう出る:
[root@raidserv] (~/.bitcoin)# grep “No,” debug.log No, were not changing any damn priority No, were not changing any damn priority No, were not changing any damn priority No, were not changing any damn priority …
これで bitcoind を一日中動かしっぱなしにしても、ほとんど気にならなくなった……
ラズロがこれを修正したが、残念ながら 0.3.0 に間に合わなかった。ただ、おそらく近いうちに 0.3.1 が出るだろう。
問題は、PRIO_MIN を使用していたことだ。最低優先度には PRIO_MAX を使うべきだった。OS は優先度を上げさせないようになっているので、PRIO_MIN は優先度0 のまま残すはずだ。