广告

利用数据流语言简化并行编程

2010-11-05 Casey Weltzin 阅读:
毫无疑问,目前常用的高层抽象和API极大简化了设计过程,但大多数方法仍需要人工识别并行代码部分,并要考虑竞态条件以及并行任务之间的同步等等问题。随着单颗芯片上的CPU内核数量不断增加,想要充分利用多核硬件优势的相关应用,很可能会遭遇并行编程的痛苦。基于数据流的一类编程语言,不仅能显著简化针对今天的多内核处理器开发代码的过程,而且能够成为发挥未来更多内核CPU优势的关键策略。

不管是修改现有应用程序还是编写全新代码,设计并行应用程序所面临的挑战要比顺序程序艰巨得多。

毫无疑问,目前常用的高层抽象和API极大简化了设计过程,但大多数方法仍需要人工识别并行代码部分,并要考虑竞态条件以及并行任务之间的同步等等问题。随着单颗芯片上的CPU内核数量不断增加,想要充分利用多核硬件优势的相关应用,很可能会遭遇并行编程的痛苦。

基于数据流的一类编程语言,不仅能显著简化针对今天的多内核处理器开发代码的过程,而且能够成为发挥未来更多内核CPU优势的关键策略。

顺序搜索

在寻求并行编程挑战的解决方案时,首先认识到目前编程语言和并行处理器架构之间的不匹配,是很有帮助的。

随着处理器硬件的发展,嵌入式工程师和计算机科学家编写的程序通常都与硬件结构直接相关。在最基本的层次,这种概念在汇编语言中非常突出,因为在汇编语言中都是直接操作处理器的寄存器。

现代编程语言

现代编程语言已经提升了其抽象层次,除了人工线程操作外,还提供基于任务的API和并行结构。但嵌入式编程有一个方面基本保持没变:编程是按顺序逐行方式进行的,所模拟的是在大多数微处理器上单线程执行的顺序行为。

这与流程图方法有很大区别,后者正是许多工程师针对某项应用展开头脑风暴时所追求的。流程图方法不是立即集中处理按照CPU架构要求的一组顺序步骤,而是让编程人员更直接地解决他们想要解决的问题,方法是集中精力于操作数据需要的算法上,以及这些算法之间的从属性。

另外,流程图是以直观可视方式表达并行过程(没有数据依赖性的过程)的一种自然选择。

传统的做法要求编程人员在CPU实现之前将流程图部分转换为顺序语句——这是不仅费时,而且对并行任务来说相当困难的任务。然而,经过十多年研发推出的编程语言,可以直接编码函数和数据依附信息,从而使转换步骤变得不再必要。参考数据流语言可以发现,它们有一个无法被忽略的重要优点:自动识别代码的并行部分并在多内核处理器上予以执行的能力。

简而言之,传统编程语言要求编程人员将他们的想法适应顺序执行模型,并人工识别代码的并行部分。而今天的数据流解决方案,能够使用智能编译器检测并行机制(图2),然后选择如何最佳调度顺序型CPU指令。这是一项根本性的改变,它能让开发人员集中精力解决手头的问题,而不是去处理底层硬件。

图2:数据流编译器可以自动识别代码并行部分,并在运行时通过调度在多内核CPU上执行。
图2:数据流编译器可以自动识别代码并行部分,并在运行时通过调度在多内核CPU上执行。

{pagination}

并行应用程序本质

虽然数据流应用程序可以用文本方式编写(例如大家常见的VHDL),但数据流源代码经常用图形方式表达,这样能最清晰地向编程人员传达数据关系和并行机制。

考虑如下一个基本算术操作的源代码:

结果 = ((B * C) + A) / (D - E)

用美国国家仪器(NI)公司的LabView数据流语言编写的程序如图1所示。

图1:描述了一个基本算术操作的数据流图例。注意,加法、乘法和减法节点并不相互依赖,因此可以并行执行。
图1:描述了一个基本算术操作的数据流图例。注意,加法、乘法和减法节点并不相互依赖,因此可以并行执行。

与顺序语言相比,这种图形化数据流表达方式有两个重要特性:首先,并行操作的直观可视性能够让编程人员快速判断程序元素相互间的关系。从图1可以明显看出,加法和乘法节点,完全可以与减法节点同时运行。

其次,智能编译器可以完成相同的观察,并将源代码示意图中的各个部分划分成独立的小部分,然后分配给不同线程进而在多内核处理器上执行。

这可不是学术性研究。这样的数据流技术如今已经完全商用化,而且越来越多的语言正在增加数据流扩展功能,从而使开发人员能够获得数据流并行编程带来的好处。

出于解释的目的,我们对图1所示的算术例子进行了简化。在实际应用中,数据流源代码可能包含信号处理算法、库调用以及大多数任何现代编程语言中常见的其它结构和操作。

无论是创建只有两条并行路径的小程序,还是具有上百条并行路径的大程序,都可以利用数据流编程语言的固有并行机制,充分发挥多内核CPU硬件的优势。

虽然编译器能够自动将数据流代码映射到并行处理器,但并没有排除开发人员的所有责任性和控制能力。基本的并行编程技术,如任务并行机制、数据并行机制和管线,都可以用数据流代码自然实现,从而优化应用程序性能。取决于具体的数据流编程工具,也可以对人工线程和同步化进行支持。

图3:使用并行编程模式,如管线(本图所示)、任务并行机制和数据并行机制,有助于优化在多内核CPU上执行的数据流应用程序。
图3:使用并行编程模式,如管线(本图所示)、任务并行机制和数据并行机制,有助于优化在多内核CPU上执行的数据流应用程序。

图3显示了采用数据流语言的管线式实现例子。图中管线用单位延时单元(箭头)表示,它存储运算结果,并将结果传送给后续循环中的另外一个节点。围绕图中单元的灰色边界,代表一个while循环。

学习曲线

就像所有其它技术一样,数据流语言同样也有缺点。首先也是最重要的一点是,因为数据流范例与传统顺序语言有很大区别,习惯于顺序语言的编程人员必须克服学习曲线才能顺利过渡到数据流语言。

为了降低过渡的难度,像LabView等数据流语言可以采用不同的方式输入现有的C代码甚至.m文件脚本,从而方便了大量现有代码的复用。

另外,数据流语言依靠通过引用的存储器访问的缺失,将并行代码部分自动映射到多内核CPU;通常只允许通过值的访问。虽然这样可以让编程人员以最小的代价充分发挥并行硬件的优势,但也可能增加应用程序的存储器占用量。

先进的数据流编译器试图通过使用各种技术减轻对存储器占用量的影响,这些技术的目的是尽量减少使用的存储器位置数。

不过对许多个人来说,相比传统语言和工具,数据流语言和他们熟悉的流程图之间的相似性使得他们更容易学习和使用。

展望未来

考虑未来多内核CPU会使用哪种编程语言的一个好途径,就是仔细研究目前被广泛使用的大量并行硬件设备中的一种:现场可编程门阵列。像VDHL和Verilog等硬件描述语言,常用于对FPGA进行编程,而且它们依赖开发人员来规定逻辑算法和数据依赖性——这是一个很好的数据流例子。

随着CPU的不断发展,机构和独立的编程员都应认真看待数据流,并把它作为多内核编程挑战的潜在解决方案。不管下一代并行CPU采用何种具体形式,有件事情是肯定的:开发人员需要继续寻找新的方法,如数据流,以便充分利用这些CPU,并减轻并行编程带来的痛苦。

作者: Casey Weltzin

实时解决方案产品经理

   美国国家仪器

本文为EET电子工程专辑 原创文章,禁止转载。请尊重知识产权,违者本司保留追究责任的权利。
您可能感兴趣的文章
相关推荐
    广告
    近期热点
    广告
    广告
    可能感兴趣的话题
    广告
    广告
    向右滑动:上一篇 向左滑动:下一篇 我知道了