首页 > 编程知识 正文

java测试函数运行时间,sql里关于时间到函数

时间:2023-05-05 12:58:51 阅读:215044 作者:3051

时钟机制是驱动Linux内核运转的核心组件,他的工作方式有两种,periodic(周期性的)和NO_HZ_FULL(IDLE).在不同的模式下,时钟周期的精度是不同的,下面做实验验证一下.

测试用例:

#include<stdio.h>#include<stdlib.h>#include<time.h>#include<sys/time.h>#include<errno.h>#include<string.h>#include<unistd.h>#include<sys/types.h>#include<sys/select.h> int main(int argc, char **argv){ unsigned int nTimeTestSec = 0; unsigned int nTimeTest = 0; struct timeval tvBegin; struct timeval tvNow; int ret = 0; unsigned int nDelay = 0; struct timeval tv; int fd = 1; int i = 0; struct timespec req; unsigned int delay[20] = {500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0}; int nReduce = 0; //误差 fprintf(stderr, "%19s%12s%12s%12sn", "fuction", "time(usec)", "realtime", "reduce"); fprintf(stderr, "----------------------------------------------------n"); for (i = 0; i < 20; i++) { if (delay[i] <= 0) break; nDelay = delay[i]; //test sleep gettimeofday(&tvBegin, NULL); ret = usleep(nDelay); if(ret == -1) { fprintf(stderr, "usleep error, errno=%d [%s]n", errno, strerror(errno)); } gettimeofday(&tvNow, NULL); nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec; nReduce = nTimeTest - nDelay; fprintf (stderr, "t usleep %8u %8u %8dn", nDelay, nTimeTest,nReduce); //test nanosleep req.tv_sec = nDelay/1000000; req.tv_nsec = (nDelay%1000000) * 1000; gettimeofday(&tvBegin, NULL); ret = nanosleep(&req, NULL); if (-1 == ret) { fprintf (stderr, "t nanousleep %8u not supportn", nDelay); } gettimeofday(&tvNow, NULL); nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec; nReduce = nTimeTest - nDelay; fprintf (stderr, "t nanosleep %8u %8u %8dn", nDelay, nTimeTest,nReduce); //test select tv.tv_sec = 0; tv.tv_usec = nDelay; gettimeofday(&tvBegin, NULL); ret = select(0, NULL, NULL, NULL, &tv); if (-1 == ret) { fprintf(stderr, "select error. errno = %d [%s]n", errno, strerror(errno)); } gettimeofday(&tvNow, NULL); nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec; nReduce = nTimeTest - nDelay; fprintf (stderr, "t select %8u %8u %8dn", nDelay, nTimeTest,nReduce); //pselcet req.tv_sec = nDelay/1000000; req.tv_nsec = (nDelay%1000000) * 1000; gettimeofday(&tvBegin, NULL); ret = pselect(0, NULL, NULL, NULL, &req, NULL); if (-1 == ret) { fprintf(stderr, "select error. errno = %d [%s]n", errno, strerror(errno)); } gettimeofday(&tvNow, NULL); nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec; nReduce = nTimeTest - nDelay; fprintf (stderr, "t pselect %8u %8u %8dn", nDelay, nTimeTest,nReduce); fprintf (stderr, "--------------------------------n"); } return 0;}

在使用高精度定时器的情况下测试开关PREEMPT的情况:

关闭CONFIG_PREEMPT的情况下

打开CONFIG_PREEMPT

重新编译和安装内核:

貌似改善不多,可以得出CONFIG_PREEMPT和精度关系不大的结论,我们继续.

打开周期定时器:

关闭高精度定时器:

运行用例验证,可以明显发现,由于时钟模式变为periodic的了,时钟粒度瞬间缩减为4ms=4000us,所以例子中即便睡眠1个us,也需要等到4ms后才会被唤醒.和没有打开periodic的模式有显著区别.

CONFIG_HZ修改为100,看有没有变化:

重新编译内核,发现时钟粒度再次变大,CONFIG_HZ从250变为100. 时钟粒度则从4ms变为10ms成反比关系.

打开CONFIG_HIGH_RES_TIMERS

重新编译,运行用例:

可以看到,打开高精度定时器,时间精度恢复了原始的比较精确的误差范围.

关闭CONFIG_NO_HZ

发现时间精度仍然是高精度的范围

所以看起来,控制告警定定时器的是CONFIG_HIGH_RES_TIMERS.

结束!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。