ほとんどのLinuxシステムでは、jiffiesのデフォルト値は250(4ms)です。問題は、プログラムのusleep()時間が4ms未満の場合はどうなりますか?もちろん、意図したとおりに動作します。しかし、他のプログラムを実行する必要があるため、Linuxスケジューラがプログラムをスタンバイ状態にする場合はどうなりますか?この場合、プリエンプションはどのように機能しますか?
待ち時間がこのように短いカスタマイズされたプログラムは避けるべきですか?正確ではないでしょうか?
答え1
バラより時間(7)、そしてそれが参照するマンページです。抜粋:
High-Resolution Timers
Before Linux 2.6.21, the accuracy of timer and sleep system calls (see
below) was also limited by the size of the jiffy.
Since Linux 2.6.21, Linux supports high-resolution timers (HRTs),
optionally configurable via CONFIG_HIGH_RES_TIMERS. On a system that
supports HRTs, the accuracy of sleep and timer system calls is no
longer constrained by the jiffy, but instead can be as accurate as the
hardware allows (microsecond accuracy is typical of modern hardware).
You can determine whether high-resolution timers are supported by
checking the resolution returned by a call to clock_getres(2) or look‐
ing at the "resolution" entries in /proc/timer_list.
HRTs are not supported on all hardware architectures. (Support is pro‐
vided on x86, arm, and powerpc, among others.)
1つのコメントは、あなたはそのような短い時間は眠ることができないと言った。 HRTではそうではありません。このアプリを試してください。
/* test_hrt.c */
#include <time.h>
main()
{
struct timespec ts;
int i;
ts.tv_sec = 0;
ts.tv_nsec = 500000; /* 0.5 milliseconds */
for (i = 0; i < 1000; i++) {
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
}
}
コンパイル:
$ gcc -o test_hrt test_hrt.c -lrt
走る:
$ time ./test_hrt
real 0m0.598s
user 0m0.008s
sys 0m0.016s
ご覧のとおり、0.5msの遅延で1000回繰り返すのに予想通り、0.5秒が少しかかりました。clock_nanosleep
本当に次の瞬間が戻ってくるのを待つなら、少なくとも4秒はかかるでしょう。
今、最初の質問は、「計画がその時間の間予定されている場合はどうなりますか?」です。答えは優先順位によって異なるということです。他のプログラムがスケジュールされている間にプログラムが実行されていても、プログラムの優先順位が高い場合、またはスケジューラーがプログラムの実行時間であると判断した場合は、タイムアウトが返されたclock_nanosleep
後に再実行が開始されます。それが起こるために次の瞬間まで待つ必要はありません。 CPUを多用する他のソフトウェアを実行している間に上記のテストプログラムを実行すると、このプログラムがまだ同時に実行されていることを確認できます。特に、以下を使用して優先順位を上げる場合はさらにそうです。
$ time sudo schedtool -R -p 99 -e ./test_hrt
答え2
リアルタイムカーネルを実行しない限り、とにかく10ms未満の省電力時間は使用しません。スケジューラがタイムアウト時に他のプロセスを喜んで先取りしても、ジッタは実際のスリープ時間を支配できます。
要約:リアルタイムカーネルがない場合は、このような小さな間隔を避けてください。カーネルを変更できない場合の最善の方法は、SCHED_FIFOを使用してプロセスを専用のCPUに固定し、約2フィート未満で忙しい待機(またはその他の有用なタスク)を実行することです。
なんだか要約がオリジナルより長くなりましたね…ああそうですね。