linux内核将ticks / jiffies更改为高于1000的hz

时间:2015-10-16 08:34:26

标签: c linux

在Linux中是否有可能改变它为更精细的时间分辨率打勾的速率?

在我的系统中默认分辨率设置为1000hz,这意味着我的最小延迟为1ms,我需要一个更加精确的系统,延迟为1us甚至1ns,但我不知道它是否是甚至可以将其改为超过1000hz。

如果可以改变,在哪里/如何实现?

考虑到编写c脚本,还有其他可行的解决方法吗?

1 个答案:

答案 0 :(得分:1)

当然它取决于硬件(如果是特定的嵌入式)和内核版本,但是在现代Linux中,睡眠时间不受Jiffies的控制。 2.6.24以上的Linux内核可以使用高精度事件计时器(HPET)来触发某些事件。

与应用程序睡眠无关。如果您想睡1分钟或更短时间,则无需设置CONFIG_HZ_1000

在Linux中,您可以使用usleep()nanosleep()功能。运行Ubuntu的台式机的时钟分辨率已经是1 ns。然而,这并不意味着可以在非实时系统中完美地睡眠几纳秒。

检查此示例(使用gcc clock.c -O3 -Wall -lrt -o clock编译):

#include <stdio.h>
#include <unistd.h>
#include <time.h>

int main()
{
    struct timespec res, tp1, tp2;

    clock_getres(CLOCK_MONOTONIC, &res);

    clock_gettime(CLOCK_MONOTONIC, &tp1);
    usleep(100);
    clock_gettime(CLOCK_MONOTONIC, &tp2);

    printf("resolution: %ld sec %ld ns\n", res.tv_sec, res.tv_nsec);
    printf("time1: %ld / %ld\n", tp1.tv_sec, tp1.tv_nsec);
    printf("time2: %ld / %ld\n", tp2.tv_sec, tp2.tv_nsec);
    printf("diff: %ld ns\n", (tp2.tv_sec - tp1.tv_sec) * 1000000000 + tp2.tv_nsec - tp1.tv_nsec);

    return 0;
}

默认情况下,我有超过所需睡眠时间的60个usec延迟。这种准确度对于睡眠时间可以接受几百微秒(在我的系统中CONFIG_HZ=250)。

为了减少延迟,应该以更高的优先级运行该过程,例如:

sudo chrt --rr 99 ./clock

在这种情况下,我的误差可能小于20 us。

clock_gettime的后续调用之间没有任何睡眠功能,我可以看到范围200 - 900 ns中的延迟。因此,可以通过繁忙循环以usec精度测量睡眠:

clock_gettime(CLOCK_MONOTONIC, &tp1);
clock_gettime(CLOCK_MONOTONIC, &tp2);
while (get_diff(&tp1, &tp2) < ns_time_to_sleep)
    clock_gettime(CLOCK_MONOTONIC, &tp2);