如何确保代码运行时由于缓存的执行时间没有变化?

问题描述:

在嵌入式应用程序(用C编写,在32位处理器上)上有严格的实时约束,关键代码(特别是中断)的执行时间需要保持不变。如何确保代码运行时由于缓存的执行时间没有变化?

如何确保不引入时间变化代码的执行,具体是由于处理器的缓存(无论是L1,L2还是L3)?

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

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

如果失败了,也许在软件代码的某些地方可能会写入故意用垃圾填充缓存,所以接下来发生的任何事情都可以保证是缓存未命中。做得对,可以提供可预测性,也许只能在某些地方完成,所以速度可能比完全禁用缓存更好。最后,如果速度很重要 - 仔细设计软件和数据,就好像在旧式的8位CPU编程中一样 - 保持足够小以适应L1缓存。我总是惊讶于现在的板载缓存如何比小型计算机上的所有内存更大(笨拙十年)。但这将是艰苦的工作,需要聪明。祝你好运!

两种可能性:

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

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

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

/艾伦

看来你指的是没有考虑实时系统内置的x86处理器系列,因此对于固定时间执行没有真正的保证(CPU可能会重新排序微指令,比CPU有错误预测条件跳转时每次刷新的分支预测和指令预取队列...)

了解用于复杂操作和使用定时器的最差情况运行时。

这个答案会发出嘲笑,但它的目的是让你觉得:

只运行一次代码。

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

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

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

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

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

+0

所有有效的问题,但是这个问题与没有I/O,分页,最小操作系统等的“裸机”应用程序有关。 – Benoit 2008-09-16 03:15:31

如果您在关键代码“inline”中进行所有函数调用,并尽量减少变量的数量,以便让它们具有“注册”类型。 这应该会改善程序的运行时间。 (你可能必须以特殊的方式编译它,因为编译器这些天往往忽视你的'注册'标签)

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

你也可以看看生成的汇编代码,看看是否有很多分支和内存instuctions可以改变你的运行代码。

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