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を一日中動かしっぱなしにしても、ほとんど気にならなくなった……
asdfman、その出力を生成しているプログラムは何? 気に入った 😁
ラズロがこれを修正したが、残念ながら0.3.0に間に合わなかった。ただ、おそらく近いうちに0.3.1が出るだろう。
問題は、PRIO_MINを使用していたことだ。最低優先度にはPRIO_MAXを使うべきだった。OSは優先度を上げさせないようになっているので、PRIO_MINは優先度0のまま残すはずだ。