在具有硬实时约束的嵌入式应用程序(在 32 位处理器上用 C 语言编写)中,关键代码(特别是中断)的执行时间需要保持不变。

如何确保不引入时间变化 在执行中 代码的影响,特别是由于处理器的缓存(L1、L2 或 L3)?

请注意,我们担心缓存行为,因为 巨大的 它对执行速度的影响(有时超过 100:1 vs.访问 RAM)。由于特定处理器架构而引入的可变性远不及高速缓存的大小。

有帮助吗?

解决方案

如果您能够接触到硬件,或者与能够接触到硬件的人合作,您就可以关闭缓存。有些 CPU 有一个引脚,如果连接到地而不是电源(或者可能是其他方式),将禁用所有内部缓存。这会带来可预测性,但不会带来速度!

如果做不到这一点,也许可以在软件代码的某些地方编写故意用垃圾填充缓存的方法,因此接下来发生的任何事情都可以保证是缓存未命中。如果做得好,这可以提供可预测性,并且也许只能在某些地方完成,因此速度可能比完全禁用缓存更好。

最后,如果速度确实很重要 - 仔细设计软件和数据,就像在古代 8 位 CPU 编程一样 - 保持它足够小,以使其全部适合 L1 缓存。我总是对现在的板载缓存比(十年前)小型计算机上的所有 RAM 还要大感到惊讶。但这将是一项艰苦的工作,需要聪明才智。祝你好运!

其他提示

两种可能性:

完全禁用缓存。应用程序运行速度会变慢,但没有任何变化。

将代码预加载到缓存中并“锁定”。大多数处理器提供了一种机制来执行此操作。

看来你指的是x86处理器系列,它并不是考虑到实时系统而构建的,因此不能真正保证恒定时间执行(CPU可能会对微指令重新排序,而不是有分支预测和指令预取队列)每次当CPU错误预测条件跳转时都会被刷新...)

这个答案听起来有些讽刺,但它的目的是让你思考:

仅运行代码一次。

我这么说的原因是因为太多的事情会让它变得可变,而你甚至可能无法控制它。你对时间的定义是什么?假设操作系统决定将您的进程放入等待队列中。

接下来,由于缓存性能、内存延迟、磁盘 I/O 等,您会遇到不可预测性。这些都归结为一件事:有时需要一些时间才能将信息输入到代码可以使用它的处理器中。包括获取/解码代码本身所需的时间。

另外,您可以接受多少差异?可能您可以接受 40 毫秒,也可能可以接受 10 纳秒。

根据应用程序领域,您甚至可以进一步掩盖或隐藏差异。多年来,计算机图形人员一直在渲染到离屏缓冲区,以隐藏渲染每帧时间的差异。

传统的解决方案只是尽可能多地删除已知的可变利率事物。将文件加载到 RAM 中,预热缓存并避免 IO。

如果您将关键代码中的所有函数调用都“内联”,并最大限度地减少变量的数量,以便可以让它们具有“寄存器”类型。这应该可以提高程序的运行时间。(您可能必须以特殊方式编译它,因为现在的编译器往往会忽略您的“注册”标签)

我假设您有足够的内存,当您尝试从内存加载某些内容时不会导致页面错误。页面错误可能需要很长时间。

您还可以查看生成的汇编代码,看看是否有大量分支和内存指令可能会更改您正在运行的代码。

如果代码执行过程中发生中断,则需要更长的时间。是否启用了中断/异常?

预分配内存,并确保中断不会影响缓存(不可能,对吧)。

/艾伦

了解复杂操作的最坏情况运行时间并使用计时器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top