6

nanosleepを呼び出す小さなテストプログラムが、2.6.22より新しいカーネルを搭載したLinuxマシンで実行すると、CPU使用率に大きな違いが見られることに気づきました。

#include <time.h>
int main (void)
{
    struct timespec sleepTime;
    struct timespec returnTime;
    sleepTime.tv_sec = 0;
    sleepTime.tv_nsec = 1000;
    while (1)
    {
      nanosleep(&sleepTime, &returnTime);
    }
    return 0;
}

(はい、私はこのプログラムが何もしないことを理解しています)

これをコンパイルしてopenSUSE10.3マシン(2.6.22.19-0.2-デフォルト)で実行すると、プログラムは「top」によって生成されたプロセスリストにも表示されず、CPU時間をほとんど使用していないことがわかります。 。openSUSE 11.1マシン(2.6.27.23-0.1-デフォルト)で実行すると、topはCPU時間の40%を費やしているプログラムを示しています。Fedora 9(2.6.25-14.fc9.i686)とFedora 10で実行すると、「トップ」でも同じ高いCPU使用率が示されました。

これに影響を与えるカーネルの変更はありましたか?

4

2 に答える 2

22

これは、メインライン スケジューラに NO_HZ が導入されたためです。

以前は、1,000 ns のスリープは通常、ティック全体 (1,000,000 ns) の間スリープしていました。これで、マシンが他の方法でアイドル状態になっている場合、実際には、要求したことのためにスリープ状態になっているだけです。そのため、while() ループと syscall を約 1,000 倍頻繁に実行しているため、CPU 使用率がはるかに高くなります。tv_nsec を増やすと、CPU 使用率が低下するはずです。

于 2009-07-30T05:43:25.113 に答える
3

明確な答えはありません...しかし、最初に確認するのは、カーネルがコンパイルされた構成オプションです。

cat /boot/config-`uname -r`

関連すると思われるオプションは、、CONFIG_HZです。たぶんそれらはあなたのカーネル間で異なります...それはあなたがそれを絞り込むのを助けるかもしれません。CONFIG_HPET_TIMERCONFIG_HIGH_RES_TIMERS

以前は、nanosleepがビジーになる2.4カーネル上にありました-リアルタイムスケジューラポリシーで実行している場合は2ミリ秒未満の待機を待ちます(SCHED_FIFOまたはSCHED_RRnanosleepのマニュアルページを参照)が、すべてのカーネルが2.6であるため、そうではありません要因のようです。

于 2009-07-14T14:28:56.487 に答える