中文 英语

驯服的并发

为了避免并发性错误,设计师必须跳过哪些障碍?

受欢迎程度

并发性增加了行业缺乏适当工具的复杂性,问题已经发展到没有简单或一致的方法来检测错误的情况下,错误可能会蔓延到设计中。

在过去,当芯片基本上是一个单一的管道时,这不是一个问题。事实上,早期的先驱EDA创建合适的语言来描述和包含时钟周期内和跨时钟周期存在的必要并发性。这种语言演变成了Verilog。

但是,当管道的性能不能再通过设计或设备扩展来提高时,唯一的出路就是多管道。“这一切都在2000年代中期发生了变化,当时我们不再有频率缩放,我们不再有电力效率,”克雷格·雪莉说,该公司总裁兼首席执行官Oski技术.“因此,虽然我们仍然有晶体管密度缩放,但我们必须从同步顺序设计转向并行设计。这就是并行时代的开始。”

到那时,软件行业已经牢牢地固定在顺序编程范式中,并且在系统级别上创建了绷带来延长这些方法的寿命。不幸的是,EDA行业本质上走的是同一个方向,从软件语言中添加更高级别的编程概念,而不是创建能够忠实地表示集成到单个芯片中的并发性的新级别的语言。

花在验证已经成长,并将因此继续成长。“在复杂的芯片设计中,找到极端情况下的漏洞是功能验证过程的关键部分,”英特尔公司的技术营销顾问汤姆·安德森(Tom Anderson)说OneSpin解决方案.“极端情况下的bug,反过来都是关于并发性的。当特定的事件组合同时发生并触发之前没有执行过的行为时,它们就会发生。”

问题是不可能验证所有潜在的极端情况。“我们称之为抗模拟超级细菌,”雪莉补充道。“这些功能性漏洞无法模拟,因为激活和检测它们需要极端的极端情况。它们是设计人员在并行性和并发性方面的创新的副作用,以抵消后期频率缩放的放缓摩尔定律时代。”

其中一些很难探测。“性能问题将更频繁地出现在这种类型的设计中,”拉塞尔克莱因警告说,HLS平台项目主管Mentor是西门子旗下的企业.“我在与我合作的客户中越来越频繁地看到这种情况。创建这种设计的目标是提高吞吐量和性能,但副作用和意想不到的后果会导致意想不到的性能问题。”

图1所示。可移植刺激中定义的并发性。来源:Accellera系统倡议

这一切都是因为没有办法显式地定义并发线程之间的通信。当无意或含蓄的交流发生时,麻烦就潜伏着。

语言和并发性
语言在如何指定事物方面起着至关重要的作用。Klein说:“我们现有的硬件设计语言非常擅长描述并发性。”“我看不出有什么不足。在软件方面,有很多并行编程语言,但是软件开发人员仍然坚持他们的单线程编程模型。Anant Agarwal和Tilera建立了一个技术上成功的并行软件实现方法。尽管在相同的功耗下,它的性能是传统处理器的3倍,但它从未取得太大的商业成功。随着扩展变得越来越具有挑战性,我们可能会看到软件团队重新考虑这些编程模型,作为继续提高系统性能的一种方式。”

但是在一些小众领域,并发语言已经取得了一定的成功。“如果你使用OpenMP或OpenCL在更高的层次上表达并行性,甚至cuda -现在你有了一个编译器,可以确保你没有一致性或死锁问题,”Frank Schirrmeister解释说,他是微软的高级组主管,产品管理和营销节奏.“同样的道理也适用于使用fpga.如何编写Xilinx的Zynq之类的程序?当他们说话时,他们指的是OpenCL,在那里你有能力表达并发性。然后你有一个编译器来确保依赖关系被解析。”

高级合成(HLS)是一个中间地带,业界没有定义一种合适的语言,而是朝着发现潜在并发性的方向发展。Schirrmeister补充道:“HLS的范围有限,所以它是有效的。”“重点是微架构级别,我正在展开循环,并弄清楚如何获得正确的并行级别以满足性能要求。但我不会与处理器上运行的访问该块的软件共享这种并行性。”

“高级合成工具在发现和引入并发性方面做得很好,”Klein说。在由于算法描述的性质而无法提取并发性的情况下,它将为开发人员识别依赖关系,使他们能够手动修改代码以增加并发性。然而,HLS不具有全球可见性。它不能考虑其他模块或软件中的活动。为了做好分区工作——特别是在硬件和软件之间,以及跨多个核心进行软件分区——人们需要对系统中的数据流有一个全局视图,包括硬件和软件。”

这就是问题开始的地方。

系统级的并发性
如果未指定并发,则必须发现并发。克莱因解释说:“今天,它意味着运行整个系统,包括硬件和软件,并对其进行监控。”“当然,一旦你有一个完整的系统运行,通常不会有很多重新设计的事情发生,除非它真的不能满足它的要求。这个行业确实需要一种方法来监控和查看这些硬件和软件之间的交互和依赖关系,从而引导开发人员更好地理解他们的系统。并且要在设计周期的早期,也就是可能会对当前设计产生影响的变更实施的时候。”

人们曾试图使交流更加明确。“这要追溯到阿尔贝托·桑乔瓦尼·文森泰利Schirrmeister说,他提倡以沟通为基础的设计。“通信是明确的,然后你会弄清楚如何以一种安全的方式实现通信,这样就不会出现死锁。这也是MCAPI的基础。这个API支持将通信与处理分离。MCAPI的美妙之处在于,您可以预见地说,这个块需要与那个块对话,这个处理需要与那个处理对话。所以你把通信和处理分开了。你确切地知道依赖关系是什么,你可以使用自动化来实现,使它们得到优化,永远不会失败。”

今天,硬件和软件设计本质上分别查看。“在设计过程中,系统级并发性并不是一个障碍,因为我们提供知识产权必须在不同的时间限制下的各种系统中工作,”技术副总裁彼得·格林哈尔说手臂.如果在软件层面上对并发性的控制是可见的,就会使用已建立的体系结构技术,如锁定指令(例如,负载独占,存储独占)和原子。数据完整性也可以使用跨IP的标准一致性协议(如MOESI)进行管理和维护。”

试图使硬件对异步事件不敏感是标准实践。Cadence公司HLS产品经理Dave Pursley表示:“理想情况下,你应该在设计过程中尽早发现依赖关系。“例如,你想要避免这样一个代价高昂的错误:设计了几个大的硬件块,却发现当放置在原地时,意外的计时(延迟)依赖关系会引入诸如死锁、数据丢失或内存损坏等问题。可以通过在所有硬件块上使用延迟不敏感接口来避免这些情况。完全握手确保流经系统的数据按预期处理,并且没有数据被丢弃。它还明确规定,对于块之间的定时同步没有隐藏的假设。”

这是要付出代价的。Pursley补充道:“这种方法的成本非常小,甚至可以忽略不计,只需要为区块间的握手接口增加一两个额外的比特。”“这种设计实践在设计重用IP时尤其有用。延迟不敏感接口,保证IP的未来。”

但这要付出更大的代价。如今被利用的许多安全问题和漏洞都是使隐式通信成为可能的直接结果。一致性是一个直接的结果。如果所有的交流都是明确的,那么就不需要普遍的一致性。在线程之间共享内存的能力会产生漏洞,然后需要更多的硬件来试图阻止这种情况的发生。

调试并发
并发最终会产生一个错误。“这些很难做到调试克莱因说,因为它们通常涉及跨多个处理器的软件,以及跨多个总线结构进行交互的事务。“没有很多工具可以向开发人员展示与总线事务和硬件活动相关的多个核之间发生了什么。解决这些问题所需的能见度很难达到。”

大多数情况下,它归结为特别方法。一位典型的设计师说:“我们一直依赖那些足够聪明的设计师,他们能够在头脑中理解设计的整个运作。”“当你转向更大更复杂的设计时,你会发现团队中能够做到这一点的人越来越少。在某种程度上,你达到了一个没有人能理解的阈值。当你必须跨越知识边界时,你如何发现漏洞?”

Klein表示,他看到“开发者使用了大量的$display语句,解析模拟文本,并从波形数据库中转储vcd文件。他们盯着数据看,直到开发人员有了“啊哈”的时刻。这是一种非常特别的方法,但系统的方法并不存在。”

另一种方法是添加性能限制保障措施。Schirrmeister说道:“如果你遇到了一致性问题,一种方法便是清除所有内容并回到正确的状态。“这会影响你的表现。这些问题很难发现。它们超出了ip级测试所做的一切。他们测试组件之间的相互作用。”

大多数公司试图通过两种方式来解决这些问题便携式刺激(PSS)和正式的.Schirrmeister说道:“使用PSS,你便拥有一个能够处理所有可能排列的约束求解器。“这可以让你发现是否有任何问题。调试发生在更高的级别。您可以用一种类似UML图的方式表示事物,然后查看序列图,这将显示什么被激活以及何时被激活。这使得调试问题变得更容易。”

这确实需要一种不同的方式来思考验证。“你必须把功能放在一边,测试系统组件的交互,”Dave Kelf说Breker.这包括性能和电源压力测试、系统级一致性和关键路径。这样做,可以发现更复杂的极端情况下的bug。随机系统级交互可以揭示奇怪的行为,这是专注于功能规范的工程师难以想象的,这揭示了错误或性能/功率瓶颈。”

在更抽象的模型上进行这种类型的验证也会有所帮助。“使用松散或近似定时的事务级模型(TLM)对系统的延迟和数据流进行精确建模是一种常见的方法,”Pursley补充道。“这些模型的模拟速度比RTL.更重要的是,它们在开发过程中更早地可用,通常在RTL设计真正开始之前。然后,如果在TLM模拟过程中发现了意外的依赖关系,可以修改RTL规范,以适应仅延迟不敏感接口无法避免的任何额外依赖关系。”

用于发现这些问题的另一种方法是形式化的。OneSpin的Anderson说道:“形式化验证对于发现极端情况下的漏洞尤其有效,因为它能够详尽地分析设计。“没有必要担心错过一个会发现bug的测试用例。此外,形式分析假设事件和行为可以同时发生,除非另有指定。虽然没有直接分析软件,但是许多指定设计行为的断言和约束反映了软件(和固件)如何使用硬件。这提供了一种系统级验证的度量,其确定性是任何其他方法都无法达到的。调试发生在熟悉的环境中,因为通过正式测试发现的任何错误都会在模拟测试中重现。”

前进
如果不采取行动,这个问题只会变得更糟,而不是更好。Klein说:“要真正解决系统级别的并发问题,我们应该这样做,因为好处是巨大的,在开发人员社区必须做两件事。”“一个是硬件和软件不能保持独立和不同的学科。其次,软件开发人员需要接受并行编程模型。”

Schirrmeister增加了明确并发的需求。“OpenCL正试图达到更高层次的抽象,就像MCAPI将处理与通信分离一样。如果使用了这些,那么就有可能实现自动化。可以在两个实现选项之间进行选择,例如HW和SW。当我知道所有的输入和输出,以及谁有能力与之对话时,我就可以从性能的角度来看待所有选项,并避免错误。”

当你在等式中加入力量时,问题的解决就变得更加重要。Klein总结道:“编程语言是存在的,但是采用的不多。“就性能和功耗而言,这给开发人员带来了巨大的好处。如果你看一下处理器的排列,你会发现每毫瓦最高的MIPS在最小的内核中,而不是最大的内核。如果您将软件负载分布在多个较小的处理器上,与在一个大处理器上运行单线程程序相比,您将以更低的功耗获得更快的执行速度。软件开发人员再也无法从扩展中获得提升,所以他们可能会开始寻求这些方法。”

有关的故事

使用更多验证核

当虫子逃跑时

如何处理并发



2的评论

BillM 说:

布莱恩,
如果你使用自动驾驶汽车(终端市场),以及文章中列出的问题是如何解决的,那将会很有趣。我预计汽车软件中会有大量并发事件导致许多超级bug。
比尔

凯文·卡梅隆 说:

我之前放弃了Accellera和IEEE在处理并发性和高层设计方面的努力,特别是放弃了RTL(同步FSM),转而使用数据流(异步FSM)方法(在那里更容易进行功能验证)。作为替代方案,我提出了一个扩展的c++来取代Verilog,以及一种利用遗留代码的高度并行架构的方法

http://parallel.cc

EDA行业即将发现,神经网络工程有很多类似的要求,但人工智能的家伙们将构建新的工具……

留下回复


(注:此名称将公开显示)

Baidu