如何确保代码运行,而不会因缓存而导致执行时间不变?

时间:2008-09-16 03:00:00

标签: caching time profiling processor

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

如何确保代码的执行中没有引入时间可变性,特别是由于处理器的缓存(L1,L2或L3)?

请注意,我们关注缓存行为,因为它对执行速度有很强的巨大效果(有时超过100:1与访问RAM)。由于特定的处理器架构而引入的可变性远不及缓存的大小。

7 个答案:

答案 0 :(得分:2)

两种可能性:

完全禁用缓存。应用程序运行速度较慢,但​​没有任何可变性。

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

答案 1 :(得分:2)

似乎你指的是x86处理器系列并没有考虑到实时系统,所以没有真正保证恒定时间执行(CPU可能重新排序微指令,而不是分支预测和指令每当CPU错误地预测条件跳转时刷新的预取队列......)

答案 2 :(得分:2)

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

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

最后,如果速度确实很重要 - 仔细设计软件和数据,就像在古老的8位CPU编程的旧日那样 - 保持足够小,使其全部适合L1缓存。我总是惊讶于这些日子里的机载缓存如何比小型机上的所有RAM都要大(mumble-decade)。但这将是艰苦的工作,需要聪明才智。祝你好运!

答案 3 :(得分:0)

这个答案听起来很讽刺,但它的目的是让你想到:

  

只运行一次代码。

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

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

另外,您可以接受多少差异?它可能是你没有40毫秒,或者你没有10纳秒。

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

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

答案 4 :(得分:0)

如果您在关键代码'inline'中进行所有函数调用,并最小化变量的数量,那么您可以让它们具有'register'类型。 这应该可以缩短程序的运行时间。 (你可能必须以特殊的方式编译它,因为这些天编译器往往忽略你的'寄存器'标签)

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

您还可以查看生成的汇编代码,看看是否有很多分支和内存可能会改变您的运行代码。

如果代码执行中发生中断,则需要更长时间。你有中断/例外吗?

答案 5 :(得分:-1)

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

/阿伦

答案 6 :(得分:-1)

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