数据流(dataflow)编程是针对当前大规模密集型计算领域和多核处理器体系结构的特点而设计的一种新的编程模型。它最早作为一种被叫做同步数据流(synchronous dataflow, SDF)的计算模型而被提出。同步数据流是数据流的一种特例,它是在计算机学科的并行计算领域流行的一种硬件与软件相结合的方法学。
简介数据流编程是一种解决多核处理器的效率利用问题的高性能并行编程模型。数据流编程与传统编程语言有着明显区别,它通过数据驱动的方式执行,将需要处理的数据分配到各个核上,将数据的计算与通信相分离,通过任务调度与分配,利用软件流水的并行特性来充分的挖掘流程序中潜在的并行性,使各个核之间负载均衡。在数据流范例中,一个数据流程序的静态实例会按照它的结构被描述成一张有向图。图中节点表示计算单元,边代表数据传输路径。相邻节点间通过边传输数据,节点消耗数据进行计算,并将产生的数据输出到输入输出序列作为下一个计算单元的输入。
数据流编程语言数据流编程语言主要关注程序的状态,并根据状态的变化导致操作发生。数据流编程语言本质上是并行的,因为操作依赖于满足时会导致操作执行的输入。这意味着与一个正常程序不同,后一个操作后跟着一个操作,在数据流程序中,只要满足输入并且没有设定顺序,操作就会执行。 通常,数据流编程语言使用大型哈希表,其中键是程序的数据,而表的值是指向程序操作的指针。这使得多核程序更易于在数据流编程语言中创建,因为每个核心只需要散列表就可以工作。 数据流编程语言的一个常见示例是电子表格程序,它具有受其他数据列影响的数据列。如果一列中的数据发生变化,其他列中的其他数据可能会随之变化。
应用流编程模型的数据流编程语言(Data Flow Programming Language)是一种面向领域的编程语言(Domain Specific Language,DSL),将流应用领域中以数据为驱动和功能独立的特性融入语言中,将计算和通信分离,同时隐藏通信的具体细节。一系列独立的计算单元中蕴含了大量的并行,采用数据流语言进行编程的难点在于如何充分利用流应用中的潜在并行性,如何利用数字媒体领域的流程序的特性来对流程序的调度划分进行优化。当前主要的流编程语言,有Stream It和 CUDA,它们针对不同的专业应用,如 Stream It 主要针对科学计算与编解码处理,而 CUDA 主要针对 GPU 应用。这些语言对于不同的体系结构支持不够,存在一定的局限性。
麻省理工学院(MIT)的 Saman Amarasinghe 教授带领的团队设计出一种 Stream It数据流编程语言,它是为了方便大规模的流应用编程而开发的流编程模型,同时,Stream It 能够适用于多样的体系结构,包括现有的商业型的单处理器,多核结构以及集群平台。在 Stream It中的基本计算单元叫做 filter,它是一个单输入单输出程序块,程序块中是用户定义的将输入数据转换成输出数据的过程。每一个 filter 都包含一个用作初始化的 init 函数以及用来描述稳态下最细粒度过程的 work 函数。filter 能够通过FIFO 队列与它相邻的 filter 进行通信,并且使用了 push、pop 和 peek 操作,这 3种操作所需用到的窗口值大小在 work 函数中指定。filter 组合的基本程序设计结构有3 种,分别是 pipeline、splitjoin 与 feedbackloop。
Imagine是斯坦福大学开发的一种可编程流处理器,它采用了一种新的层次化的流编程模型,该模型将数据组织成流,将计算单元表示成核心(kernel),Imagine 在计算时分为两级:流级和核心级,这两级分别在主机和 Imagine 上运行。Imagine 流编程模型的主要目标是能够很好的开发数据的并行性,由于它支持的 SIMD 方式要求程序具有简单的控制机制,因此,kernel的主要组织方式是循环结构。流语言从 MIT 的 Stream It 后来又发展到了 UMich 的Flexstream。这种新的流编程模型比 Stream It 更为灵活,而且它在 Stream It 的基础上增加了动态调度部分,这种调度策略会根据底层结构的改变来相应的改变流程序的调度和划分方法,从而使得流程序的效率不会随着底层平台的改变而大幅降低1。
数据流数据流是指一组有顺序的、有起点和终点的字节集合,程序从键盘接收数据或向文件中写数据,以及在网络连接上进行数据的读写操作,都可以使用数据流来完成。数据的性质、格式不同,则对流的处理方法也不同,因此,在Java的输入/输出类库中,有不同的流类来对应不同性质的输入/输出流。在java.io包中,基本输入/输出流类可按其读写数据的类型之不同分为两种:字节流和字符流。
输入流与输出流
数据流分为输入流(InputStream)和输出流(OutputStream)两类。输入流只能读不能写,而输出流只能写不能读。通常程序中使用输入流读出数据,输出流写入数据,就好像数据流入到程序并从程序中流出。采用数据流使程序的输入输出操作独立与相关设备。输入流可从键盘或文件中获得数据,输出流可向显示器、打印机或文件中传输数据。
缓冲流
为了提高数据的传输效率,通常使用缓冲流(Buffered Stream),即为一个流配有一个缓冲区(buffer),一个缓冲区就是专门用于传输数据的内存块。当向一个缓冲流写入数据时,系统不直接发送到外部设备,而是将数据发送到缓冲区。缓冲区自动记录数据,当缓冲区满时,系统将数据全部发送到相应的设备。
当从一个缓冲流中读取数据时,系统实际是从缓冲区中读取数据。当缓冲区空时,系统就会从相关设备自动读取数据,并读取尽可能多的数据充满缓冲区。
本词条内容贡献者为:
李岳阳 - 副教授 - 江南大学