我正在尝试确定我可以准确安排在 C/C++ 中发生的任务的粒度。目前我可以可靠地安排任务每 5 微秒发生一次,但我正在尝试看看我是否可以进一步降低它。
任何关于如何实现这一点的建议/如果可能的话,将不胜感激。
因为我知道计时器粒度通常取决于操作系统:我目前在 Linux 上运行,但如果时间粒度更好,我会使用 Windows(尽管我不相信它是基于我对 QueryPerformanceCounter 的发现)
我在裸机(无 VM)上执行所有测量。/proc/timer_info
确认我的 CPU 的纳秒计时器分辨率(但我知道这不会转化为纳秒警报分辨率)
当前的
目前,我能够每 5 微秒(5000 纳秒)执行一次请求,延迟到达率不到 1%。当确实发生延迟到达时,它们通常只落后一个周期(5000 纳秒)。
我现在正在做 3 件事
将进程设置为实时优先级(@Spudd86在这里指出了一些)
struct sched_param schedparm;
memset(&schedparm, 0, 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, 0, &timspec, 0);
可能的改进
- 专用处理器来处理这个过程?
- 使用非阻塞 timerfd 以便我可以创建一个紧密循环,而不是阻塞(紧密循环会浪费更多 CPU,但也可以更快地响应警报)
- 使用外部嵌入式设备触发(无法想象为什么会更好)
为什么
我目前正在为基准测试引擎创建工作负载生成器。工作负载生成器使用泊松过程模拟到达率(X 个请求/秒等)。从泊松过程中,我可以确定必须从基准测试引擎发出请求的相对时间。
因此,例如,每秒 10 个请求,我们可能会在以下时间发出请求:t = 0.02、0.04、0.05、0.056、0.09 秒
这些请求需要提前调度,然后执行。随着每秒请求数量的增加,调度这些请求所需的粒度也会增加(每秒数千个请求需要亚毫秒级的精度)。因此,我试图弄清楚如何进一步扩展这个系统。