哪些中间表示可用于推理并发?


12

我试图更好地理解编译器能够代表程序员对并发做出明智选择的要求。我意识到例如这个问题有很多困难的方面:

  • 确保没有比赛条件
  • 确保要同时运行的代码不会产生影响代码语义的副作用

  • 给定代码中可用的并行度,确定是否有必要分散线程的开销

我的理解是,现代编译器中使用的两个主要中间表示形式是面向过程和面向对象语言的静态单一分配,以及面向功能语言的延续传递样式。使用这些中间形式似乎很难对上面列出的任何问题进行推理。即使是理论上应该在自动并行化方面机会最大的语言(诸如Haskell这样的纯功能语言,也没有副作用)在这方面也取得了有限的进展。

所以我的问题是,实际上使用了哪些中间表示来尝试解决该问题?我还不知道还有其他一些学术研究中使用的表示形式更适合此任务吗?这个问题是否是编译器前端必须从根本上通过在编译到达中间表示之前操纵抽象语法树来解决的问题?


如果您以功能性的方式编写代码,则不必担心竞争状况或副作用。
罗伯特·哈维

4
这并不能完全回答您的问题,但是您可能对可用于推理并发代码的Process Calculi感兴趣。最著名的例子可能是Pi微积分。但是,自动并行化仍然是一个未解决的问题,可以通过专门设计为编译器提供某些保证的语言或使用特殊注释来最好地解决。
阿蒙2014年

4
作为英特尔并发集合(CnC)的背景论文列出了八种基本的并发模式,例如Producer-Consumer。这些并发模式又取决于许多属性,例如不变性和无副作用。(如果有人能总结该论文并在此处作为答案,我将不胜感激。)
rwong 2014年

理论上的工具之一是建立在SSA之上的“动态单一分配(DSA)”。
rwong 2014年

@rwong:您可以提供明确的参考吗?
Ira Baxter 2014年

Answers:


5

有人认为,在中间表示(IR)中显式建模并发是一项必要的要求。因此,一个答案将是:“任何用于顺序程序的IR都需要添加一些并发操作”,例如“ fork and join”,“ parallel x y”。添加这些使得可以推理某种并发,但不一定很容易。如何确保某些属性(数据争用自由度)而又不一直使用完整的功能表示(这使得很难有效地建模并行性)也不是显而易见的。

有争议的彩色Petri网(CPN)是表示并发程序的不错选择。(CPN中的令牌是“有颜色的” [具有类型],并且可以携带值;将“状态”转换为状态可以对传入的令牌执行任意算术,以在“位置”中生成计算值的可能不同颜色的令牌)。如果将场所视为建模结果的计算结果和转换(包括用于访问内存的特殊运算符),那么这将为您提供一个数据流图,可以用来对程序进行建模。您可以轻松地使用它来对经典的编译器表示形式(例如,三元组[operator,input1,input2,output])进行正式解释。

有很多工具可以分析此类CPN图,包括计算属性,例如无死锁,位置中令牌计数的有界性等。分层CPN使您可以对函数和过程以及“调用”的概念进行建模。

这些表示方式并没有明确地做的是,使人们很容易推断出可以在哪里并行化应用程序。琐碎地讲,如果两个子计算没有共享操作数的副作用,那么它们可以是并行的(这就是为什么有些人喜欢功能程序/表示的原因)。如果您的程序表示模型对共享内存进行建模,则可以将其建模为整体,并获得有关共享内存上交互作用(包括别名寻址等)推理的常见问题集。避免这种情况的一种方法是将内存视为带有较大的程序状态是其中的一些(树状)组合;您可以说可以在中间表示形式中传递这些块。如果两个并行计算不共享块(例如,内存子树),则它们之间没有交互。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.