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

发布于 2024-07-04 14:49:27 字数 234 浏览 11 评论 0原文

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

如何确保代码执行中不会引入时间可变性,特别是由于处理器的缓存(无论是 L1、L2 还是 L3)?

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

In an embedded application (written in C, on a 32-bit processor) with hard real-time constraints, the execution time of critical code (specially interrupts) needs to be constant.

How do you insure that time variability is not introduced in the execution of the code, specifically due to the processor's caches (be it L1, L2 or L3)?

Note that we are concerned with cache behavior due to the huge effect it has on execution speed (sometimes more than 100:1 vs. accessing RAM). Variability introduced due to specific processor architecture are nowhere near the magnitude of cache.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

前事休说 2024-07-11 14:49:27

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

Understand your worst case runtime for complex operations and use timers.

惜醉颜 2024-07-11 14:49:27

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

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

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

If you can get your hands on the hardware, or work with someone who can, you can turn off the cache. Some CPUs have a pin that, if wired to ground instead of power (or maybe the other way), will disable all internal caches. That will give predictability but not speed!

Failing that, maybe in certain places in the software code could be written to deliberately fill the cache with junk, so whatever happens next can be guaranteed to be a cache miss. Done right, that can give predictability, and perhaps could be done only in certain places so speed may be better than totally disabling caches.

Finally, if speed does matter - carefully design the software and data as if in the old day of programming for an ancient 8-bit CPU - keep it small enough for it all to fit in L1 cache. I'm always amazed at how on-board caches these days are bigger than all of RAM on a minicomputer back in (mumble-decade). But this will be hard work and takes cleverness. Good luck!

从来不烧饼 2024-07-11 14:49:27

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

仅运行代码一次。

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

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

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

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

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

This answer will sound snide, but it is intended to make you think:

Only run the code once.

The reason I say that is because so much will make it variable and you might not even have control over it. And what is your definition of time? Suppose the operating system decides to put your process in the wait queue.

Next you have unpredictability due to cache performance, memory latency, disk I/O, and so on. These all boil down to one thing; sometimes it takes time to get the information into the processor where your code can use it. Including the time it takes to fetch/decode your code itself.

Also, how much variance is acceptable to you? It could be that you're okay with 40 milliseconds, or you're okay with 10 nanoseconds.

Depending on the application domain you can even further just mask over or hide the variance. Computer graphics people have been rendering to off screen buffers for years to hide variance in the time to rendering each frame.

The traditional solutions just remove as many known variable rate things as possible. Load files into RAM, warm up the cache and avoid IO.

信愁 2024-07-11 14:49:27

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

It seems that you are referring to x86 processor family that is not built with real-time systems in mind, so there is no real guarantee for constant time execution (CPU may reorder micro-instructions, than there is branch prediction and instruction prefetch queue which is flushed each time when CPU wrongly predicts conditional jumps...)

夜声 2024-07-11 14:49:27

两种可能性:

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

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

Two possibilities:

Disable the cache entirely. The application will run slower, but without any variability.

Pre-load the code in the cache and "lock it in". Most processors provide a mechanism to do this.

初心未许 2024-07-11 14:49:27

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

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

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

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

If you make all the function calls in the critical code 'inline', and minimize the number of variables you have, so that you can let them have the 'register' type.
This should improve the running time of your program. (You probably have to compile it in a special way since compilers these days tend to disregard your 'register' tags)

I'm assuming that you have enough memory not to cause page faults when you try to load something from memory. The page faults can take a lot of time.

You could also take a look at the generated assembly code, to see if there are lots of branches and memory instuctions that could change your running code.

If an interrupt happens in your code execution it WILL take longer time. Do you have interrupts/exceptions enabled?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文