Approximate Computing. A Survey


  • 尽管半导体科技以及能效设计技术在不断发展,但是计算机系统为了处理不断增加的信息,整体的能耗仍然在以令人担忧的速度不断增长。尤其是,随着计算机系统普及开来,计算机系统就用来与物质世界做交互同时用来处理从不同地方获取到的大量信息。此外,我们还希望它们能够识别不同的语境并且提供一种自然的人类接口。因此,出现了大量的应用,主要包括识别应用、挖掘应用以及综合应用,这些应用构成了从移动端和物联网设备到数据中心之间计算资源的一个重要组成部分。
    为了能够跟上需要处理的信息发展速度,极大地改善这些新兴出现的设备的能耗效率是很有必要的。幸运的是,这些应用一般来说有一个内在的错误恢复的性质。它们处理一些冗余并且有噪声的数据,这些数据来自于一些非传统的输入,例如,不同的种类的传感器(非精准输入),并且一些相关的算法在本质上通常是随机的(例如,迭代算法)。此外,这些应用通常不需要计算出一些独一无二的或者非常精准的结果(结果一般来说要求是可以接受的而不是精准的)。例如,在多媒体处理中,由于人类有限的感知能力,一些偶然的错误,例如,丢失某一个帧的数据或者说一个小的图像质量损失都很少影响到用户的体验。以数据分析中的一个情况作为另一个例子,考虑有两个不同的分类器,这两个分类器对同一个数据集会产生类似的分类结果。鉴别哪一种分类器用于分类新事物的效果更好是非常困难的。
    另一方面,随着半导体科技进一步进入了纳米的时代,为了保证没有错误的运算是需要消耗非常多的功率的。这是因为在低电压和不断增长的集成密度的情况下,电路对先进技术节点的参数变化和故障更为敏感。传统的无差错计算为了可接受的误差和错误校正,需要在不同层的设计层次结构中加入防护带宽以及一定的冗余量,这一点导致了巨大的能源开销。
    受到上述的挑战的激励,一个有前途的解决方案吸引了来自工业界和学术界的目光。通过放宽错误容忍应用的指标和实际之间的等效范围,近似计算故意把可接受的误差引入计算过程并且保证了巨大的能效降低的收益。考虑到传统的Dannards缩放定理(随着MOSFET面积不断变小,由于单位面积的功耗是固定的,因此功耗与MOSFET成比例)说明集成电路生产技术进步带来的功耗收益越来越少,利用近似计算来实现功耗的降低已经越来越重要。
    近几年来,在不同计算层次中的不同的近似计算技术已经在各种论文中被称述了。此篇文章的目的有两个。第一,我们提出一些现有的近似计算工作的观点并且通过一篇对文献综述巩固现有的一些结果和见解。请注意,我们并不会对文献进行一个完整的综述,而是对技术发展水平的一些关键方面进行阐述。第二,我们很重视开放的挑战并且讨论了一些未来的研究方向。通过与最近的一些综述作对比,我们的分类和组织结构是完全不同的并且我们的视角由于遍布整个计算层次所以也更宽。
    此文剩下的内容是按照如下进行展开的。近似计算范例部分主要概括了近似计算的范例。在近似软件、近似结构以及近似电路板块,我们调查并且巩固了一些技术,这些技术主要与如下内容相关,近似软件开发,近似结构探索以及近似电路设计,我们对每一个方向的技术都有所覆盖。最后,我们在挑战和未来研究方向板块,提出了一些挑战并且指明了未来在近似计算方向中的研究方向。

近似计算范式

计算已经进入了一个近似的时代,在这个时代中硬件和软件生成和推理估计。导航应用通过GPS传感器的硬件,估计出地图和位置,把这些信息转换为驾驶的方向信息;语音识别把模拟的信号转换为一个最为可能的语句;搜索引擎软件把搜索请求转换为信息。这些复杂的系统需要及其精巧的算法才能够大规模地、尽快地、低功耗地给出足够好的结果,在这一过程中,往往近似计算是唯一一个能够达到上述目标的方式。在这一个板块中,我们简短地来看一下近似计算的范例。
对于已经给定的可以容忍一定错误的应用,应用近似计算的一个整体的框架在图1中显示出来。框架中的关键组成部分如下所述。
近似内核。近似内核指的是那些用来实现近似计算以达到减少功耗目的的技术。通常来讲,有两种不同种类的近似计算内核。在硬件层面,我们要么可以用一些不那么精准的但在功效方面表现更好地电路来实现计算或者有意图地减少一些硬件部分的电源电压来在功耗和精准度之间做平衡。在软件层面,我们可以选择性地忽略一些特定的计算或者或者存储器的访问,这些计算或者存储器访问对最终的用来实现相同目标的应用质量没有关键的影响。
从软件层面到电路层面的一些代表性的近似计算内核描述在表1中。

弹性识别和特征 即使是一些能够容忍错误的应用,对错误敏感的部分使用一些非精准的计算会引起一些致命性的错误。因此,部署近似计算关键的一步就是去识别哪些弹性错误部件可以被用来使用近似计算。
弹性识别对的一种方法是标记应用或者使用精心设计的近似数据类型来表示哪些位置可以用来实现近似计算以及它们会如何影响结果。另外,我们可以把应用分成好几个部之后,来实现每一个部分的敏感度分析。有一部分部件可以被很容易地分类为敏感的或弹性的。对于那些剩下的部分,我们可以通过注入错误和仿真的方法来评估近似计算对他们的影响。如果某些部件在注入错误时,应用崩溃了或者说产生了一些不可接受的结果,那么这个部分就可以被标注为错误敏感的;反之,它就是弹性的。然而,如果仿真不够充分,这种方法也有可能是有风险的因为仿真有可能没能够捕捉到一些情况,在这些情况中,崩溃的数据所产生的的效果没有被立刻显示出来。
在弹性识别之后,我们需要描述不同近似方法对于不同弹性部件所产生的影响,那么这通常是通过使用一些仿真技术或者说让部件执行一些代表性的工作。注意,由于实际生产环境中在系统上执行的工作有可能会和仿真的有所不同,为了保证最终的应用质量,去做一些动态质量管理的工作往往是很有必要的。
质量管理 在动态质量管理中,我们评估中间每一步的计算质量(最好是通过应用定制的轻量型检查器)并且决定在运行时的什么时候要使用近似计算方法以及对应的近似模式。
SAGE和GREEN在每N次对近似计算内核调用之后立刻检查输出的质量,在这之中,他们对比了近似计算和精准计算之间的质量并且相应地调整了接下来计算需要使用的的近似模式。很显然,通过这样一种质量采样的策略,质量检查得越频繁,最终应用质量的可靠性就越高,但是能耗也随之升高。另一方面,利用这种模式对每一次内核调用都进行监视也是不现实的,因为这种方式违背了近似计算的初衷。
上述的质量采样定理有一个重要的问题那就是我们绝无可能保证那些没有被检测到的输出质量的好坏。因此,连续的质量检测是更好的一种方法。毫无疑问,只能使用小开销的检测器,只有这样才不至于使从近似计算中获得的好处消失。受到大型认知性预测工作的启发(例如分支预测和值预测),一些在近似计算中使用的质量预测期被很多文献提出。在[21]中,Ringenburg和他的同事们介绍了一种所谓的模糊记忆的技术,这种技术记录了被检测代码先前的输入和输出并且也通过先前类似输入的记录来预测当前执行的输出内容。近似的质量是通过检测预测结果和实际结果之间的差距,从而被估计出来。Rumba通过观察近似加速器对的输出和输入,从而构建了多种简单的错误预测模型。如果一个很大的近似错误被检测到的话,那么需要进行精准计算来实现对错误的校正。
在接下来的板块中,我们将会详细讨论不同计算层次中使用的近似计算方法。

近似软件

一个好的编程语言需要让编程人员变得更加高效。这种编程语言能够让编程人员迅速地表达他们的想法同时也要让编译器和运行时系统能够优化程序的执行过程。编程语言和他们的实施平衡着编程者的效率和系统的有效性。
编程语言是通过“抽象”这一方法来实现对两者的平衡的。抽象能够让程序员表达完成一个任务该做什么而不是该怎么做。这种怎么做——或者说是抽象的一种具象——是留给编译器和运行时系统去完成的。
简历精巧的应用是非常难得并且需要系统全栈的技术,在这个近似的时代下,这些技巧包括统计学(或者一些其他的意识到近似的推导)以及特定应用层面的知识。许多学者提出抽象这个概念来帮助程序员来完成这项烦人的工作也不足为奇了。这种抽象帮助程序员在程序(例如有近似意识的编程语言)中表达自己的想法,让分析引擎推导程序的正确性(例如有近似意识的分析),并且让编译器产生机器码(例如有近似意识的编译器)。
接下来的板块主要描述了最近学术界和工业界在有近似意识的编程语言、分析以及编译器这几个方向上取得的成果。

有近似计算意识的编程语言

有近似计算意识的编程语言让程序员能够表达在哪里和有多少随机性能够影响到他们的结果。在1979年,Kozen意识到符号和语义对于那些在执行过程中有随机性的程序是很有必要的。这项早期工作的目标是使用编程语言通过概率结构来确定程序的含义。这项工作给一个简单的概率语言提供了两种语义——一个是给采样建立模型,还有一个是直接计算概率分布——然后还证明了它们是等效的。这个结果表明了接下来的工作可以直接用采样来近似计算概率分布。
程序中随机性的表达 大量的后继研究工作中的语言让程序员能够表达多大的随机性会影响到他们的程序。例如,程序语言比方说Eon,EnerJ以及Rely把近似通过编程语言的符号提供给程序员。考察EnerJ和Rely这两种语言,它们让程序员能够用近似类型的信息来注释他们的程序。在EnerJ中程序员必须显式地把近似类型转换为精确类型,然而在Rely语言中,编译器尝试去从统计角度来推理一个近似的类型怎么转换为其他类型。
库函数,比方说Uncertain,提供了一种抽象,这种抽象把近似的数据封装在标准的面向对象编程语言中,并且通过运行时的程序变量来传递数据。当一个程序需要利用近似数据时,Uncertain运行时利用假设检验来作出统计意义上正确地分支决策。
有近似意识的编程语言的关键挑战是把这个推理过程尽可能自动化从而程序员不需要理解很多关于近似计算如何会影响他的程序的准确性的细节。
通过概率编程进行推断 大量的工作尝试通过建立一个由Kozen提出的理论结构体的方式来解决这个问题。概率编程语言把概率的语言叠加在现有的编程语言。这些语言的主要目标是用观察到的事实对概率推断的有效实施然后根据事实推断程序中变量的概率分布。全为的概率编程案例解决了如下问题,“给定机器草是湿的这一事实,需要判断产生这一现象的原因是因为下雨还是因为洒水车撒的水?”。作为一个概率的程序,程序员需要把这个概率模型描述出来,或者需要把程序中变量之间的关系描述出来(例如,下雨的可能性以及当下雨的时候,人们不太可能会用洒水器),之后,给定一个现象(例如,草是湿的),之后,概率编程运行时会依据给定的现象或条件推断出魔性的各种性质。
这些编程语言吧推断的细节抽象出来,也因此这些语言被机器学习专家们用来建立他们的模型。概率编程语言在推广概率推断这方面取得了重要的进展;他们让机器学习专家把他们的模型转换成代码,并且通过概率推断提出复杂的需要大量计算的关于模型的问题。总体来说,概率推断问题是NP问题,是比较难的问题,并且大多数概率编程语言学术研究都是在研究如何让概率推断变得效率更高。
一些概率编程语言,例如Church,可以在他们支持的所有分布上做概率推断。其他的概率编程语言牺牲表达性来换取性能,还限制了他们所支持的分布,这也因此让概率推断更容易处理也更加高效。Infer.NET使用多种近似推断引擎以及精确推断引擎,每一种推断引擎都会有不同的限制。
举一个具体的例子,考虑一个简单的在LINQ中的概率编程实现,在这种实现中,开发者把概率程序和程序的推断表达为一个LINQ请求。在列表1a的第一个程序提供了一种二项分布的实现方法,第二段程序说明了通过一个LINQ中的where语句,如何增加条件——或者说是事实。这些程序使用LINQ来美剧所有抛硬币的可能性,并且求出边缘概率分布是概率推断的任务,边缘概率分布可以把程序输出映射为可能性。例如,运行Inference将会导致一个结果。
这个简单的案例清晰地表明了概率推断中间的一些难点,对于所有的那些小型应用来说枚举一个程序中所有的可能路径是不现实的(这种推断的实施在随机原语的数量上呈指数增长)。对于概率编程的深入理解是:(1)让程序员可以简易地表达一个概率程序,在此基础之上一个运行时可以高效地开始做推理的工作而不是把程序所有的可能性全部枚举一遍。概率编程的社区对这个目标实现了突破,在这个程度上,推理可以成为一种抽象,这种抽象把近似结构和和为近似结构定制的程序统一为一个整体。换句话说,给定一个程序推断,可以让我们推断出一个结构必须提供的可分配的近似硬件范围,从而能够保证某种性质的正确性以及程序的质量条件限制。

有近似意识的分析

分析的目的是为了建立程序某个部分语义的模型或者理解部分程序的语义。可能性建模被广泛用在计算机系统对的设计和分析,并且在近几年已经越来越重要。这个部分主要简述了这个领域的最近的工作。
模型的检查 概率模型的检查是一种自动化的程序,这个程序是为了确定一个一个需要的性质是不是已经被加载到概率系统之中。传统的模型检查器让程序员正式地描述一个状态转移的系统(通常以时序逻辑的形式被表达出来)并且模型检查器提供了系统性质的正式保障。相反,一个概率模型检测器需要程序员来用概率来确定系统的状态变化并且因此提供了概率上的保障。现在比较流行的工具MRMC和PRISM已经在多个领域中使用了,应用场景覆盖了从分析无线协议的源代码中的错误到在自动驾驶中给人类司机行为进行建模。
概率准确度 相似地,一些研究把一些更加传统的程序分析方法应用到了概率领域。例如,在给定两种非常相似的输入的前提下,概率静态程序分析方法计算了大输出偏离的可能性边界值。这些分析推断出在近似硬件上工作的软件通过有精确意识的改变发生了变化,并且可以接收不确定的输入。相似地,动态程序分析通过一些有代表性的输入,使用程序估计了大输出偏差的可能性。
近似,有可能通过近似硬件和编译器变形实现,或者通过让运行时来平衡应用的准确性以及功耗和性能来实现。最近著名的工作研究了最优化以及或变化,这些在精确度的限制下最优化了功耗。这一种探索通过动态测试完成或者在统计上减少为一种优化问题,之后使用线性或者整数数学算法即可完成。

有近似意识的编译器

有近似意识的编译器除了有近似意识的编译器,也可以使用近似(推断的或者说显式表达的),来自动转换并且因此改变了程序的语义,从而牺牲程序结果的准确性来换取更好的性能或者更低的能耗。例如,循环渗透技术是一种软件上的技术,这种技术修改了程序,从而让程序执行更少的迭代,也因此让程序跑得更快。一个编译器可以把确定那一部分需要使用近似计算完成的工作自动化。相似地,Stoke减少了编译时浮点数运算的位宽,牺牲精确度来换取性能。Sampson和他的同事们阐述了如何通过对值得概率分布,从程序对值的实际操作中提取程序的语义。因此,他们采用了一种变形,这种变形并不遵循原始程序的语义,但是在统计上维持了原先程序的语义,并且表明了这些变形显著地提升了程序的运行时速度。最后,Schkufza和他的同事们介绍了一种“随机超级优化”的方法,这是一种利用蒙特卡洛马尔科夫链来寻找没有循环的86代码中可以被优化的空间。他们的编译器并没有在产生代码的时候就引入近似计算,而是使用了一种近似的方法来产生快速的代码,而不需要编译器知道任何x86代码的语义,仅仅需要知道如何加入、修改以及删除单独的x86代码。

近似计算的架构

一个计算机系统的关键硬件组成部分是处理器、内存以及存储器。对于这些硬件组成部分,电脑架构师们想要在给定例如面积以及功耗的技术指标的各种限制前提下,平衡性能与功耗。对于内存以及存储器,架构师们尝试去平衡密度(或者说是没比特的成本)和性能。
但是,同时优化这些部件的性能、能耗以及密度是非常困难的,因为通常是以牺牲另一个指标的前提下提升的某个指标。例如,一个激进乱序的的构建技术提高了处理器的性能,但是因为电路和微结构复杂性的增加,使功耗大幅上升。另外,内存和存储器的密度越大,计算机读写信息的速度就越慢。
近似计算的出现引入了另一个可供考虑的折中的方向,那就是计算的质量与性能、功耗以及密度之间做平衡;略微牺牲计算的质量可以提高性能或功耗或密度。
这一个板块主要介绍了最近的一些工作,这些工作提出了一些利用近似计算来用计算质量换取能效或性能这样的一种基于处理器、存储器或者内存的子系统架构。

近似处理器

支持近似计算的处理器架构可以被分为两个不同的类。第一个分类中的处理器主要目的是为了给那些在跑在通用处理器上的通用代码提供近似支持,这些通用处理器在高效地在近似模式下,执行一些指令或者或者代码块。另一种近似处理器把可近似计算的程序段或者传统代码变形为一种类似神经网络的算法,使它能够在加速器上运行。这两种处理器都是需要编译器或者程序员来识别或者标注可以被近似的代码段。
使用增强型通用处理器的近似计算 在使用增强型通用处理器的近似计算中,需要分析传统的代码,并且代码块或者指令的精确计算部分以及可近似部分需要被标注出来,就像近似计算软件板块说的那样。因此,可以做出不同的微架构的选择来高能效地执行一些可近似的指令或代码块;可近似的指令或代码块可以被一些高能效但不可靠的数据通路以及在粗或者细调节状态下的核心执行。
对于那些细粒度近似计算,一个指令集架构定义了一系列特殊的指令,这些指令让编译器能够表达什么东西可以被近似而不需要解释如何进行近似。为了避免一些动态错误检查以及错误恢复的开销,这种指令集架构的目标就是提供一种严谨的近似程序风格。之后,微架构可以从一系列近似技术中选择一个而不需要把他们暴露出来。总的来说,近似技术可以被分为运行时近似技术以及设计时近似技术。例如,一个编译器可以提供既精确又近似的数据通路,就像图2中描述的那样。近似数据通路可以使用一个工作在加强电压上的电压或者是工作在有精度限制的特殊设计的数据通路。
对于那些粗粒度近似计算,可近似的程序段可以被加载到处理器中那些高能效但不怎么可靠的核心,之后结构性的的选择与细粒度近似计算中非常相似,在运行时和设计时选用那些不可靠但高能效地核心。例如,一个处理器由均匀同质的核心组成,这些核心中的部分被设计来通过牺牲计算精度以及偶尔的计算错误来实现高能效。
这些之前讨论的处理器架构可以被很容易地在一些包含近似指令与近似程序段的传统的应用被采用,但是它们的能效好处是有限的因为受到了传统的冯诺依曼处理器架构的限制——冯诺依曼架构采用的是指令存取与控制,数据在处理器内存结构之间交换以及处理器中所有时序部件时钟是统一的。尽管这些部件的能耗可以通过近似计算或者容许错误降低,但他们能耗仍然是现代通用计算机最主要的能耗。
通过算法变化来实现近似计算 一个数据或计算密集型的近似代码段可以通过一个鹦鹉变换(parrot transformation)被转换为一个被神经网络启发的一个算法,例如人工神经网络(ANN),从而进行更高效地进行处理。变换的代码主要是被加载到神经网络加速器中国,这些加速器由一个主加速器耦合起来,见图3。编译器通过调用神经网络硬件自动地实现这一系列的神经变换以及自动决定那一部分代码可以被近似计算,这些神经网络硬件加速了线程的速度。因为神经网络类的算法其内在是对错误弹性的,神经网络加速器可以以不同方式被架构和优化,为了能够实现最好的能耗。神经网络加速器板块讨论了不同的底层实施以及它们的优势和劣势。

近似内存以及存储器结构

近似内存以及存储器结构设计主要牺牲数据的质量来换取(1)更小的芯片及内存芯片,这些芯片可以工作在更低的工作电压以及提供对于粒子撞击的更强的保护(2)更低的DRAM能耗(3)更快的固态内存,这些固态内存能够有更长的寿命(4)更大的内存通道带宽。
内存 当工作电压低于某一特定值的时候,一些芯片级的SRAM单元就不能工作了,这一点确定了整个芯片的最低工作电压以及限制了最大的功耗。更进一步,SRAM单元非常容易受到粒子流撞击的影响。因此,为了能够获得一个更低的工作电压以及对粒子流撞击更强的保护,需要一个有更多更大晶体管的更大的SRAM单元。但是用大SRAM单元来构建芯片级的SRAM内存的成本在很多方面都很高。为了能够在内存上降低成本,如果对于一些不重要的数据在精度上的要求可以放松的话,可以给最低位的数据使用一种小的SRAM单元。这种设计技术可以仅通过可以被忽略的计算质量损失来显著地减少芯片级内存在空间和能量上的损耗,同时提供相同程度的对粒子流撞击的保护。
DRAM刷新的操作构成了DRAM芯片功耗的主要损失部分来源,刷新率通常取决于一小部分的比较弱的单元。为了减少DRAM的能量损耗,一个间隔更长的刷新率被应用到DRAM的列上,这些部分存储了一些错误弹性的数据(可以近似的数据)。因为采用间隔更长的刷新率的话,仅仅很少一部分的单元会出现错误,这对于计算质量的影响可以忽略不计,但这一技术大大降低了DRAM刷新消耗的能量。
存储器 固态内存可以让我们从一个存储单元中读写多种状态。但是为了精确地从一个单元中读取更多的状态,这是非常困难的。另一方面,如果精度要求可以被忽略,并且偶尔的不精准可以被忍受的话,这些状态可以被更容易地读写。这种固态内存的性质可以被利用来在更短的延迟内,读写对错误弹性的数据。这一种技术可以通过牺牲某些数据的质量,显著地降低内存的延迟。更进一步,对错误弹性的数据可以被存在代码块中,这些代码块已经被损坏,并且通过优先提供错误纠正的硬件资源给更加重要的那些已经损坏的为来控制那些不可能被校正的数据位。这种技术可以通过引入可以忽略的数据质量丢失来延长内存的寿命。
互联 新兴的应用都是数据密集型的,因此也需要比较大的内存带宽。为了增加内存带宽,必须增加数据传输速率或者内存通道的数量,但是这是非常困难的以内由于严格的针脚和功率限制。为了更加高效地使用给定的数据带宽,数据可以在送入存储器信道之前/后被压缩/解压缩。这种方法通常采用一种无损压缩算法但是它所能带来的好处(即,有效数据传输速率)经常被有多少给定的数据可以被压缩所限定(即,压缩比)。为了更进一步1改善压缩比,从而进一步改善数据传输速率,我们可以采用一种有损的数据压缩算法来处理一些对错误弹性的数据因为这一部分数据的精度损失是可以接受的。

近似电路

对于一个给定的电路来说,我们通过降低它的电源电压来降低能耗而不需要降低其对应的工作频率。可以利用这种所谓的过缩放技术来实现近似计算。但是,这种由于过缩放导致的数据通路的时序错误往往会导致非常巨大的计算错误,除非利用一种缩放友好型的方式来设计电路。但是,即使是利用了这种缩放友好型,在能耗上取得的收益相对来说非常少。因此,文献提出的主要的近似电路方案转向了功能上的近似,在这种发难中电路的原始功能就被有目的地设计,为了在功耗与准确性中寻找到一个折中。
在这个板块中,我们首先介绍了不同的近似算术单元设计,这些设计通常是手工设计的以你为他们有着很广泛的应用以及充分研究过的结构。接着,我们讨论了给通用逻辑电路近似的近似综合解决方案。最后,我们引入了一种神经网络加速器,这种加速器可以获得巨大的能耗收益。

近似算术单元

因为加法器是RMS应用中的关键算术电路,许多文献已经提出了很多近似加法器的设计。Jiang和他的同事们给出了一种在该领域近期工作的对比点评。我们会在加下来介绍一些有代表性的近似加法器设计。
在某种文献的设计中,一种晶体管级的近似设计被用来设计近似加法器单元。把这种加法器与传统的镜像加法器单元作对比,我们会发现最激进的一种近似实现的布局面积仅仅是传统加法器的三分之一。为了保持一种合理的输出质量,这种加法器仅仅可以用在最低位的加法这种。在Kim和他的同事提出的一种进位舍弃加法器中,这种加法器用了分割方法去吧进位传播链分割为几个部分,并且每个部分的计算时基于由低位的部分传递来的进位信号进行的,这种进位信号是通过低位的部分的位来估计出来的。
因为不同应用在运行时对精度的要求有可能有巨大的区别,最好是使用一种精确度可以配置的近似计算单元设计。工程师可以把原先的加法器分割为好几个子加法器,之后合并子加法器的部分和,从而产生最终的结果。为了减少错误,引入了一种错误检测和校正单元,我们可以通过控制在计算过程中校正数量的多少来配置运行时的准确度。例如,在Ye和他们的同事提出的一种方案中,一种可配置的近似加法器设计可以做到逐步降低计算的质量,在他们的方案中,近似计算错误可以被最高位和最低位校正。图4中,这种加法器包括了几个k位的子加法器,这些加法器的进位可以选择从更低位的加法器进位获得或者从预测部件中获得。通过设置子加法器的长度并且控制多路选择器的信号,加法器的精度不仅是可调节的,并且更重要的是,它可以逐步地降低精度,因此可以获得一个更好的对于计算质量和实现困难程度上的折中。
另外一个非常重要的用在计算中的计算单元是乘法器。在这个领域中已经有了部分工作成果,并且基本的设计原则与近似加法器的设计原则类似。一个高能效地乘法器是由2*2的近似乘法器构成的,在这种乘法器在[52]中被提出来。在[53]中,提出了体用近似加法器来组建一个可以配置计算精度的近似乘法器。

近似电路综合

当我们可以为了通用逻辑电路,手动地用一些知名结构来设计一些近似加法单元,最好是利用一些自动化的综合技术来简历他们的近似方案从而能够降低设计繁琐程度。
不像算术单元,没有一种可以被广泛采用的近似电路的误差模型。因此,这项工作的关键难点在于近似综合如何能够高效地表示出算术质量限制条件并且把他们高效地带入综合过程。
早期这个领域的设计采用了一种非常简单的误差模型。综合的问题被等效为这样的一个问题,给定一个错误率的限制条件之后,寻找到一种能够在最小面积下实现的近似方案。之后,错误率和误差程度都被考虑了进来,在这个过程中,为了解决这个问题一种两步式方案被提了出来。在第一阶段中电路仅仅是在错误程度的限制下进行综合。之后在第二阶段中,获得的电路需要进行不断地迭代优化来满足错误率的限制。SALSA把计算质量限制编码为一种虚拟逻辑函数并且用“Approximation don’t care”来简化电路,这种想法源于对于计算质量的宽限。通过这种方法,设计者可以明确额更加复杂的计算质量限制条件。另一个SALSA的优势是它可以为了近似电路综合,复用那些不再使用的逻辑综合工具。上述的技术主要应用在近似组合逻辑之中。ASLAN能够综合近似时序逻辑,它是通过利用虚拟时序计算质量限制条件电路来通过扩展SALSA实现的。
近期Tazdanbakhsh和他的同事们提出了一系列Verilog语言中的标记,把它命名为Axilog来实现近似硬件设计。Axilog能够让设计者来近似设计中的某个部分,并且同时还能保证关键部分的计算精度。虽然这个语言有很大的潜力,但是如何在逻辑综合中高效地利用这种语言扩展仍然是一个未探索的问题。
最后,最近也有一些学者尝试开发更高层次的近似电路综合工具,在这些方案中,运算符变形、位宽优化以及有近似意识的列表规划这几种方法都用来实现电路简化。

神经网络加速器

神经网络在本质上是一种通用的近似函数。随着近似计算范式的出现,他们被提出来,来加速一些对错误弹性的应用。一大部分工作主要研究神经网络的硬件实现,并且他们可以通过数字逻辑、模拟信号或者混合信号电路进行实现。总的来说,数字实现提供了一种高精度更高可靠性的解决方案,模拟信号和混合信号在结构上更为紧凑并且在能效上更高效。需要注意的是模拟电路好混合信号电路的实现以及通过科技缩放来获得好处要比数字电路更为困难。因此,为了确定神经网络加速器的模拟实现方法是否比数字实现更为优秀,需要通过一个非常彻底的研究来决定,这是因为不同的大规模集成电路的可集成性以及可生产性产生的实际的问题。
最近,一种通过记阻元件实现的RRAM的横梁结构阵列获得了大量的关注因为这种设备可以实现超级大的集成密度。因为这种技术可以自然地近似矩阵向量的乘法而不需要实际的计算,我们可以利用这种元件来实现近似计算。当把这种元件与它的同样功能的数字实现进行对比时,这种方案能够产生数量级上的优势。尽管这种技术有很大的潜力,基于RRAM的系统仍然面临了诸多挑战。首先,在基于RRAM的模拟数据处理单元以及剩下的系统之间的接口的能耗开销是非常大的,这种超大能量开销会把近似电路缩小的功耗补偿回来。第二,RRAM设备的非理想因素,例如信号的波动以及处理偏差让近似计算的质量更加困难

挑战以及未来的研究方向

当近似计算在近些年获得了非常多的关注,这个领域仍然处在发展的初期。目前的解决方案主要集中在硬件或软件的单一层面的技术栈中,并且大多数的的工作仅仅是一些应用面比较狭窄的方案。然而,不像过去硬件软件可以通过一个稳定的统一接口(即,ISA指令架构)互相独立地产生进步,如果应用不能够有效地把自己的精度需求与底层的硬件进行沟通并且在运行时监控运算质量的话,寄希望于系统能够在给定质量限制条件下获得预期的能耗收益是不现实的。仍然有部分研究尝试去构建近似计算新的硬件或软件接口,但是这种通用的解决方案通常把包袱丢给程序员来保证应用的质量因此也阻碍了这些方案的实际落地。
并且,软件工程——构建复杂可靠地代码——被抽象和成分构成实现,这是通过布尔代数和其他的工作来实现的。我们仍然没有一个等小的方法来明确、描述以及推理不可靠的硬件单元、APIs或者更高层次的库函数,这些东西能够产生一些不确定的结果。例如,许多近似计算的工作目前为止证明了输出图像并且询问读者来根据主观上判断画是不是足够好来进行评分。尽管这能够实现终端用户的认知学习,但它仍然没有对系统产生一个正式的推理。为了应用科学上的和工程上的方案来设计、优化以及生产近似计算系统(从硬件上以及软件上),我们仍然需要来把终端用户的认知标准转化为一种可定量可测试的每一个部件以及他们的解决方案的指标的接下来的几个问题。第一,一个芯片生产商如何能够确定生产线上的产品的一个部分符合了交货的标准?(或者说保证了某个确定部分的的近似计算的质量)。第二,硬件应该如何被描述?第三,软件应该以来哪一种架构上的保证?第四,数据库的API函数应该如何被确定,从而能够实现错误的引入或者把错误从输入传递到输出?最后,哪一种程序设计语言以及工具能够捕捉到编程者的意图并且帮助他们来实现一个需求?
总结一下 目前近似计算的的工作在某些领域有重大的前途,但是仍然需要重大的革新以及研究工作来使近似计算称为一个实际可用的主流计算范式。


文章作者: 南航古惑仔
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 南航古惑仔 !
  目录