使用Haskell实现大规模的实时系统:如何(如果?)?

我一直很想知道是否有可能将Haskell的强大function应用于embedded式实时世界,并且在Google上search到了Atom包。 我假设,在复杂的情况下,代码可能会有所有经典的C错误 – 崩溃,内存损坏等,然后需要追溯到原来的Haskell代码,造成他们。 所以,这是问题的第一部分:“如果您有Atom的经验,那么您是如何处理debugging编译的C代码中的低级错误并将其修复到Haskell原始代码中的呢?

我search了更多Atom的例子, 这个博客文章提到了C代码22KLOC(显然没有代码:), 包含的例子是一个玩具。 这个和这个引用有一些更实际的代码,但是这是结束的地方。 我在这个主题中提出“相当大”的原因是,我最感兴趣的是如果你能分享你在300KLOC +范围内生成C代码的经验。

由于我是一名Haskell新手,显然还有其他的方式,由于我未知的未知,所以没有find其他的方法,所以在这方面的任何其他自我教育的指针将不胜感激 – 这是问题的第二部分 – “Haskell做实时开发的其他一些实用方法是什么?”。 如果多核也在图片中,那是多余的:-)

(关于Haskell本身用于这个目的的使用:从我在这篇博文中读到的内容来看,Haskell中的垃圾收集和懒惰使得它在调度方面非常不确定,但也许在两年之后有所改变。是我能find这个话题最接近的)

注意:上面的“实时”会更接近“硬实时” – 我很好奇,如果可以确保主任务不执行时的暂停时间在0.5ms以下。

在Galois,我们使用Haskell做了两件事情:

  • 软实时(操作系统设备层,networking),其中1-5毫秒的响应时间似乎是合理的。 GHC生成快速的代码,并有很多支持调整GC和调度程序以获得正确的时间。
  • 对于真正的实时系统,EDSL被用来为其他语言生成代码,从而提供更强的时间保证。 如Cryptol,primefaces和副驾驶。

所以要小心区分EDSL(Copilot或Atom)与主机语言(Haskell)。


关键系统的一些例子,在某些情况下,还有由Galois编写或从Haskell生成的实时系统。

EDSLs

  • 副驾驶:硬实时运行监视器 – 用于实时航空电子设备监视的DSL
  • Cryptol中的等效性和安全性检查 – 关键系统的密码组件的DSL

系统

  • HaLVM–用于embedded式和移动应用的轻量级微内核
  • TSE – 跨域(安全级别)networking设备

安德鲁,

是的,通过生成的代码将问题debugging回原始源代码可能会非常棘手。 Atom提供的一种方法是探测内部expression式,然后离开用户如何处理这些探测器。 对于车辆testing,我们build立一个发射器(Atom),并通过CAN总线stream出探头。 然后,我们可以捕获这些数据,将其格式化,然后使用GTKWave等工具在后期处理或实时查看。 对于软件仿真,探针的处理方式不同。 不是从CAN协议获取探测数据,而是使用C代码挂接来直接提升探测值。 然后将探测值用于unit testing框架(与Atom一起分发)以确定testing是否通过或计算模拟覆盖率。

Haskell系统需要很长的时间才能适应小内存,并且可以保证次毫秒的暂停时间。 Haskell实现者社区似乎对这种目标没有兴趣。

使用Haskell或类似Haskell的东西对于非常高效的编译有着健康的兴趣; 例如, Bluespec编译为硬件。

我不认为这将满足您的需求,但如果您对函数式编程和embedded式系统感兴趣,您应该了解Erlang 。

我不认为Haskell或其他垃圾收集语言非常适合硬实时系统,因为GC倾向于将其运行时间分解为短暂停顿。

在Atom中编写程序并不完全在Haskell编程,因为Haskell在这里可以被看作纯粹的预编程器,用于编写实际的程序。

我认为Haskell是一个非常棒的预处理器,使用DSEL就像Atom可能是创build大规模硬实时系统的好方法,但是我不知道Atom是否符合要求。 如果没有,我敢肯定这是可能的(我鼓励任何人!)实施一个DSEL。

像Haskell这样的一个非常强大的预处理器为低级语言开辟了一个巨大的机会,通过代码生成来实现抽象,而实现为C代码文本生成器则更加笨拙。

我一直在和Atom玩弄。 这是非常酷的,但我认为这是最好的小型系统。 是的,它运行在卡车和公共汽车上,并且实现了真实世界的关键应用程序,但这并不意味着这些应用程序必然是庞大或复杂的。 这实际上是为了实时应用程序,并竭尽全力让每一个操作都花费相同的时间。 例如,不是有条件地执行可能在运行时间上不同的两个代码分支之一的if / else语句,而是有条件地select两个计算值中的一个之前总是执行两个分支的“mux”语句(所以总数无论select哪个值,执行时间都是相同的)。 除了通过Atom monad传递的GADT值执行的内置types(与C相当)之外,它没有任何重要的types系统。 作者正在开发一个静态validation工具,用于分析输出C代码,这非常酷(它使用SMT解算器),但是我认为Atom会受益于更多的源代码级特性和检查。 即使在我的玩具大小的应用程序(LED手电筒控制器),我犯了一些新手的错误,有人可能会避免更有经验的人,但这导致了错误的输出代码,我宁愿被编译器而不是通过testing。 另一方面,它仍然处于0.1版本,所以毫无疑问将会有所改进。