在POSIX中以微秒粒度调度事件

前端之家收集整理的这篇文章主要介绍了在POSIX中以微秒粒度调度事件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试确定可以准确计划在C/C++中发生的任务的粒度.目前,我可以可靠地安排任务每5微秒发生一次,但我试图看看是否可以进一步降低这一点.

关于如何实现这一目标的任何建议/如果可能的话,将不胜感激.

因为我知道计时器粒度通常可以依赖于操作系统:我目前在Linux上运行,但如果时序粒度更好,则会使用Windows(虽然我不相信它,基于我在QueryPerformanceCounter中找到的)

我在裸机上执行所有测量(无VM). / proc / timer_info确认我的cpu的纳秒定时器分辨率(但我知道这不会转换为纳秒警报分辨率)

当前

My current code can be found as a Gist here

目前,我能够每5微秒(5000纳秒)执行一次请求,迟到的次数少于1%.当迟到确实发生时,它们通常仅落后一个周期(5000纳秒).

我现在正做三件事

将流程设置为实时优先级(@ Spudd86 here指出)

struct sched_param schedparm;
memset(&schedparm,sizeof(schedparm));
schedparm.sched_priority = 99; // highest rt priority
sched_setscheduler(0,SCHED_FIFO,&schedparm);

最小化计时器松弛

prctl(PR_SET_TIMERSLACK,1);

使用timerfds(2.6 Linux内核的一部分)

int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
struct itimerspec timspec;
bzero(&timspec,sizeof(timspec));
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = nanosecondInterval;
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = 1;

timerfd_settime(timerfd,&timspec,0);

可能的改进

>将处理器专用于此过程?
>使用非阻塞timerfd,这样我就可以创建一个紧密循环,而不是阻塞(紧密循环会浪费更多cpu,但也可能更快响应警报)
>使用外部嵌入式设备进行触发(无法想象为什么会更好)

为什么

我目前正在为基准测试引擎创建工作负载生成器.工作负载生成器使用泊松过程模拟到达率(X请求/秒等).从泊松过程中,我可以确定必须从基准测试引擎发出请求的相对时间.

例如,在每秒10次请求时,我们可能会提出以下请求:
t = 0.02,0.04,0.05,0.056,0.09秒

这些请求需要提前安排然后执行.随着每秒请求数的增加,调度这些请求所需的粒度也会增加(每秒数千个请求需要亚毫秒精度).结果,我试图弄清楚如何进一步扩展这个系统.

解决方法

你非常接近vanilla Linux将为你提供的限制,它已经超越了它可以保证的范围.将 real-time patches添加到内核并进行完全抢占调整将有助于在负载下提供更好的保证.我还会从你的时间关键代码删除任何动态内存分配,malloc和朋友可以(并且将会)停止一段时间(在实时意义上)如果必须从i /中回收内存的话o缓存.我也会考虑从该机器中删除交换以帮助保证性能.将处理器专用于您的任务将有助于防止上下文切换时间,但同样,不能保证.

我还建议你小心那个级别的sched_priority,你在那里的Linux的各个重要部分,这可能会导致非常奇怪的效果.

猜你在找的C&C++相关文章