没有合适的资源?快使用搜索试试~ 我知道了~
"FAUST领域特定音频DSP语言编译为WebAssembly"
7010FAUST领域特定音频DSP语言编译为WebAssembly0Stéphane LetzGRAME,法国letz@grame.fr0Yann OrlareyGRAME,法国orlarey@grame.fr0Dominique FoberGRAME,法国fober@grame.fr0摘要0本文演示了如何使用FAUST,一种用于声音合成和音频处理的函数式编程语言,开发用于Web的高效音频代码。在简要介绍语言,编译器和允许将同一程序部署为各种目标的体系结构系统之后,将解释生成WebAssembly代码和部署专门的WebAudio节点。将呈现几个用例。进行了广泛的基准测试,以比较相同一组DSP的本机和WebAssembly版本的性能,并进行了评论。0CCS概念0•应用计算→声音和音乐计算;•软件及其工程→功能语言;数据流语言;编译器;领域特定语言;0关键词0信号处理;领域特定语言;音频;Faust;DSP;编译;WebAssembly;WebAudio0ACM参考格式:Stéphane Letz,Yann Orlarey和DominiqueFober。2018年。FAUST领域特定音频DSP语言编译为WebAssembly。在WWW'18Companion:2018年Web会议伴侣,2018年4月23日至27日,法国里昂。ACM,纽约,纽约,美国,9页。https://doi.org/10.1145/3184558.318597001 引言0FAUST[7],[8],[9]是一种用于声音合成和音频处理的领域特定语言。它被音频DSP开发人员用作C / C++的替代方案,以设计和实现高效的DSP代码作为本机应用程序或插件。作为一种多语言代码生成器构建的FAUST编译器可以轻松扩展以针对新的音频平台(第2和3节)。随着HTML5和Web AudioAPI(用于音频处理和合成的高级JavaScriptAPI)的出现,现在可以为Web开发复杂的音频应用程序。WebAudioAPI甚至提供了开发人员添加专门和高效的音频节点的可能性,以与Web Audio API本地定义的节点一起使用(第4.1至4.3节)。0本文发表在Creative Commons Attribution 4.0 International(CC BY4.0)许可下。作者保留在其个人和公司网站上传播作品的权利,并附有适当的归属。WWW'18 Companion,2018年4月23日至27日,法国里昂©2018IW3C2(国际万维网会议委员会),根据Creative Commons CC BY 4.0许可发布。ACMISBN 978-1-4503-5640-4/18/04。https://doi.org/10.1145/3184558.318597001.1 扩展Web Audio API0多年来已经开发了各种JavaScriptDSP库或音乐语言[2],[10],以扩展,抽象和增强官方API的功能。它们为用户提供了一组更丰富的音频DSP算法和声音模型,可以直接在JavaScript代码中使用。在这种情况下,开发必须从头开始,或者通过将已经编写的代码(通常是使用C / C++等实时友好语言编写的代码)调整为JavaScript。Csound团队开发了一种有趣的替代方案[5]。使用C / C++到JavaScriptEmscripten编译器,完整的C编写的Csound运行时和DSP语言现在在Web Audio API的上下文中可用。01.2 使用FAUST扩展Web Audio API0本文展示了FAUST编译链如何移至Web。在介绍语言及其编译器组织的基础上,将详细介绍用于目标WebAudioAPI和最近定义的WebAssembly低级格式的开发(第4.3至4.5节)。作为针对高度要求的数学代码的领域特定语言,从FAUST语言生成WebAssembly代码显示出特定的代码生成问题,相关领域的编译器编写人员可能会感兴趣。将介绍两个主要应用程序:在离线方式下创建可用的Web音频节点和HTML页面,使用FAUST编译器,或者更有趣和灵活的是,在Web页面中嵌入和使用编译器本身(第5节)。将呈现几个基准测试,以比较本机和WebAssembly版本的相同一组DSP的性能以及不同的WebAssembly感知浏览器的性能(第6节)。02 FAUST语言概述0FAUST是一种用于声音合成和音频处理的函数式编程语言,主要关注合成器、乐器、音频效果等的设计。它的主要灵感来源于lambda演算、组合逻辑、John Backus的FP[1]以及Stefanescu的流式代数[11]。02.1 引言0FAUST在音乐会和艺术制作、教育和研究、开源项目以及商业应用中被广泛使用。典型用户包括音乐家、声音工程师、研究人员、音乐助手等。他们通常具有信号处理背景,或者至少对音频效果和声音合成系统的工作原理或声音有清晰的理解。但用户不一定是计算机科学家或专业开发人员。0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂1+7020对于大多数用户来说,用C语言开发实时音频软件通常是难以实现的。FAUST的目标是为他们提供一种可行且高效的高级替代方案。FAUST编译器可以为多种语言生成优化代码:C++、C、Java、JavaScript、asm.js、LLVM和WebAssembly。02.2 语法和语义0正如我们将在各种示例中看到的那样,FAUST编程主要是通过使用一组二元操作来组合信号处理器。函数式编程方法特别适用于此目的。信号是离散时间函数。信号处理器是对信号进行操作的二阶函数。用于将信号处理器组合在一起的块图代数是对信号处理器进行组合的三阶复合操作的集合。最后,用户定义的函数是对块图表达式的高阶函数。强大的手段,如模式匹配,可用于算法地生成复杂的音频电路。01:+ �_0y(t < 0) = 0 y(t ≥ 0) = 1 +y(t - 1)0FAUST代码0语义块图0图1:FAUST程序具有直观的块图表示,以及简单明确的形式语义。块图是计算程序语义的有用中间步骤。0FAUST是一种文本语言,但程序可以直接转换为可视化的块图以及数学描述。FAUST编译器能够自动产生这些图表和程序的数学语义。这个特性在特别关注依赖实时程序的音乐作品的保存时非常有用。但这些特性在学习FAUST并更好地理解表达式和程序的含义时也非常有用。02.3 DSP源代码示例0这是一个用FAUST编写的简单风琴乐器(图2)。首先使用相位器周期信号连接到sin函数来定义一个振荡器信号。风琴音色定义为不同频率和音量的三个振荡器信号的总和。然后定义一个包络来应用于连续音色以构建一个声音。最后定义控制项,以作为按钮或滑块显示,用于启动音符、改变其频率和音量。0图2:用FAUST编写的简单风琴乐器示例03 编译器内部0FAUST编译器分为多个阶段,从DSP块图到信号,最后到FIR(FAUST命令表示),然后将其翻译为多种目标语言。FIR语言以通用方式描述对样本执行的计算。它包含读取和写入变量和数组的原语,进行算术运算,并定义必要的控制结构(例如for和while循环,if结构等)。此外,FAUST编译器本身已经打包为一个可嵌入的库,称为libfaust,并发布了一个基于工厂/实例模型的关联API[6]。这个模型允许开发独立的IDE,比如FaustLive [3]应用程序。03.1 FIR后端0已开发了几个后端(图3)以将FIR翻译为C、C++、Java、asm.js、WebAssembly和LLVM IR1。生成的DSP对象具有已编译时间已知的内存占用和有界的CPU使用率。它的内存在初始化时由体系结构静态分配。内存区域20与控制器值(滑块、按钮、条形图等)相对应的内存区域在外部控制代码和DSP本身之间共享。根据目标语言,每个后端都必须调整其代码生成策略,以便生成的代码可以部署和运行在执行上下文中。例如,可以使用变量名或仅索引来访问内存。一些所需的数学函数将在目标语言中可用,其他函数必须在外部找到并与生成的代码链接。01 低级虚拟机中间表示。2 作为float*或double*内存地址0Track: Web Programming WWW 2018, April 23-27, 2018, Lyon, France7030图3:编译链:从DSP源代码到输出语言0图4:从管风琴乐器编译的C++计算函数0它们的原型可能需要在所谓的导入部分生成。一些原语(如min/max)函数可能在执行上下文中可用,或者必须明确生成。C++后端通常会生成一个类,其中包含命名字段(作为整数或浮点标量或数组)来描述DSP对象的内部状态(由延迟线和控制器值组成),以及一组方法来获取/设置DSP状态,初始化它,并在每个周期处理样本。从先前描述的管风琴乐器生成的C++类的摘录显示了compute方法(图4),该方法将在每个周期使用输入/输出音频缓冲区生成样本。03.2 部署代码0然后将生成的代码与描述如何将音频计算与外部世界相关联的体系结构文件组合在一起。原生音频驱动程序被开发为基础音频类的子类,控制器被开发为基础UI类的子类。典型的图形界面0用户界面0模块0音频驱动程序模块0DSP代码0图5:DSP代码由编译器生成,音频和UI代码从通用体系结构文件中添加。0用户界面架构基于成熟的框架(如QT或JUCE),可以显示具有滑块、文本区域和按钮的即用窗口。音频和UI部分最终与实际的DSP计算结合在一起,以生成最终的音频应用程序或插件(图5)。借助这种方法,完全相同的源代码可以用于为20多个不同的目标生成本机应用程序和插件,从VST和Unity插件到Android应用程序,从嵌入式系统到Web音频应用程序。04 WEB AUDIO API0Web AudioAPI规范描述了一种用于在Web应用程序中处理和合成音频的高级JavaScriptAPI。设计模型基于音频图,其中创建一组AudioNode对象并将它们连接在一起以描述所需的音频计算。实际处理通常在底层实现中执行(通常是优化的汇编/C++代码),并且还支持使用ScriptProcessorNode接口在非实时渲染上下文中直接进行JavaScript处理和合成,从而可能导致烦人的音频故障。AudioWorklet规范旨在改善这种情况,它在主线程中完成音频图定义,但在单独的实时线程中进行渲染(包括使用纯JavaScript或WebAssembly编写的用户定义节点)。这个新规范现在可以在Chrome Canary开发版本中进行测试。04.1 从asm.js到WebAssembly0Mozilla开发人员于2011年启动了Emscripten编译器项目[12],该项目基于LLVM技术。从C/C++源代码中,它可以生成一种名为asm.js的静态可编译且无垃圾回收的JavaScript子集。这种方法取得了成功,证明了在Web上可以实现接近本机代码的性能。基于这种asm.js经验,PNaCL 4和asm.js项目的核心开发人员设计了WebAssembly5,这是一种新的高效低级编程语言,用于浏览器客户端脚本。作为一种可移植的堆栈机模型,它旨在比JavaScript更快地解析和执行。03 https://webaudio.github.io/web-audio-api/#rendering-loop 4 Google PortableNative Client (PNaCl)是一种在沙箱中运行Intelx86、ARM或MIPS本机代码子集的沙箱技术。5如asm.js模型正确完成,请参见http://webassembly.org0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂6http://kripken.github.io/emscripten-site/7https://www.mansoft.nl/csound/8https://github.com/WebAssembly/binaryen7040WebAssembly的初始目标是使用专门的编译器(如Emscripten)从C/C++进行编译,或作为其他高级或领域特定语言的编译目标。最小可行产品(MVP)规范于2017年初完成,包括二进制格式和类似传统汇编语言的文本格式。现在,所有主要浏览器都正式支持WebAssembly。使用Emscripten 6 移植成熟的C/C++代码库,如Csound7框架,或使用FAUST等DSL语言,将自然受益于改进和更稳定的性能。04.2 编译为WebAssembly0WebAssembly规范精确定义了语言的语义以及模块格式。在以前的asm.js格式的基础上,设计者决定创建一种具有模块信息密集表示的二进制编码,以实现小文件、快速解码和减少内存使用,旨在进行流式传输和动态解码。因此,二进制格式要求模块结构化,以便在解码文件时始终可用相关信息。对于开发人员来说,文本格式更简单,可以在工具上进行阅读、理解和可能的手动编写。已开发了两个新的wast和wasmFAUST后端来生成这些格式。首先完成的是wast,它生成文本人类可读的代码,更易于测试和调试。wasm生成二进制格式,可直接在浏览器或支持wasm的独立运行时中加载和执行。使用WebAssembly模块模型生成C++类的等效代码(由C++后端生成)。04.2.1模块定义。模块是WebAssembly中的可分发、可加载和可执行的代码单元,在运行时通过一组导入值(如JavaScript函数或内存段)实例化以产生实例。两个WebAssembly后端必须将中间FIR代码转换为符合所需模块格式的代码。一些专注于WebAssembly的项目(如Binaryen8)定义并实现了自己的抽象语法树模型,并提供了一个客户端API来构建、操作并将其保存为文本或二进制格式。为了避免在FAUST编译器上使用新的内存结构,并添加外部库依赖,选择不使用它们,直接使用FIR格式进行操作。04.2.2内存管理。模块在线性内存块上工作,这是一段连续的、以字节为地址的内存范围,从偏移量0开始,延伸到可变的内存大小。内存段可以在模块内部定义,也可以从JavaScript上下文中导入。由于DSP内存大小在编译时已知,因此可以轻松定义适当的内存布局来表示DSP状态。0图6:单音DSP的Wasm内存块布局0图7:多音DSP的Wasm内存块布局(这里有4个声音)0生成的DSP的内存块包含主要的DSP对象,以及内联的子对象9,以及音频缓冲区及其对应的指针10。在C++中,可以使用字段名称访问C++对象中的字段。在WebAssembly中,必须使用内存块中的索引来访问内存。因此,所有字段索引在预编译过程中计算,作为从DSP对象基地址的偏移量,以便在代码中用于加载/存储操作。当生成单个单音DSP对象时,使用模块内部内存。在我们自己定义的内存布局中,我们可以决定将DSP对象定位在地址0处,从而简化和加快对DSP字段的访问,因为它们可以简单地定义为DSP对象中的偏移量,而不必生成添加DSP基地址的代码。音频缓冲区及其指针位于DSP之后(图6)。如果DSP对象将在更复杂的内存布局中使用(例如在多音乐器中分配多个DSP对象时),则导入JavaScript创建的WebAssembly内存块。音频缓冲区及其指针从地址0开始放置,后面是DSP对象。由于每个DSP的基地址将发生变化,将生成更复杂的字段访问代码,其中添加了DSP基地址和字段偏移量(图7)。04.2.3函数生成。所有FIR函数都被编译并导出到模块的导出部分。所需的数学函数的原型不是WebAssembly的一部分。09 对于像C++这样的更结构化语言的FAUST后端通常会生成子类。10在每个周期,音频缓冲区将被复制,其中的数据来自音频包装器。0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂7050在模块的导入部分生成了Web编程WWW2018的规范,该规范将在执行时从封闭的JavaScript环境中检索。可以生成32位或64位浮点格式的代码,带有适应的数学函数和内存访问代码的版本。一些特定的函数,如整数版本的min/max函数(尚未包含在WebAssembly规范中),是在生成的代码中内部生成并内联的。必须编写专门的FIR传递11:将所有局部变量定义移动到函数的开头,或计算局部变量(堆栈/循环)及其类型等,这是二进制编码规范所要求的。代码生成需要第一遍通过计算内存中所有标量和数组字段的偏移量,然后可能需要额外的FIR传递来转换FIR或计算所需的信息。编写wast后端更容易,因为这些信息的一部分(例如具有其类型的局部变量的数量)不需要显式生成。相反,wasm后端要求更多,必须在最终代码生成之前进行几个预处理。04.2.4附加代码。在这两种情况下,DSP对象状态的完整描述将作为JSON字符串生成在模块数据段12中(包括所有控制器的内存索引)。粘合代码将获取并解码此JSON描述,并使用描述的任何部分来运行DSP代码。特别是,控制内存区域(对应于UI项目,如按钮、滑块、条形图等)可以直接由包装器代码读取/写入。04.2.5浮点非规格化数处理。当音频计算产生非规格化13浮点值时,会出现特定的问题,这在递归滤波器中非常常见。非规格化数是非常接近零的非常小的数,其不符合正常浮点数的格式。问题在于,在某些处理器上(如英特尔系列处理器)上,非规格化计算所需的计算时间比正常计算要长得多。由于音频DSP算法通常可以使用非常小的数来近似计算,并将非规格化数替换为0,因此可以在硬件级别上设置FlushToZero(FTZ)模式,以完全避免这些昂贵的计算。硬件FTZ模式在WebAssembly MVP版本中尚不可用,该版本严格遵守IEEE754标准14。FAUST编译器实现了一种自动软件策略,该策略在所有递归循环中添加FTZ代码。要激活它,必须在编译时使用-ftz编译参数:0• -ftz1模式在每个递归循环中添加一个测试,使用fabs函数和阈值来检测非规格化样本(较慢)。 • -ftz2模式在每个递归循环中添加一个使用掩码来检测非规格化样本的测试(较快)。011 FIR树可以使用类似模式的访问者进行遍历,可能进行FIR到FIR类型的转换。12http://webassembly.org/docs/modules/13https://en.wikipedia.org/wiki/Denormal_number14https://github.com/WebAssembly/design/issues/1480图8:使用Em- scripten将C++ libfaust编译为libfaust.js0即使这种策略不完美,这个额外生成的代码15将避免产生大部分非规格化值及其相关的CPU消耗峰值。04.3 Web Audio节点中的WebAssembly代码0JavaScript代码用于将wasm文件加载到类型化数组中,使用WebAssembly.compile将其编译为模块,然后使用WebAssembly.Instance函数实例化它,最后获取可调用的导出函数。DSP内存可以在wasm模块内部分配,也可以在包装的JavaScript代码中外部分配,并在创建模块时作为参数给出。创建了一个扩展的AudioNode对象16,其中包含一些附加方法。作为AudioNode类型,它可以像常规AudioNode一样使用,可能连接到其他节点等。例如,从karplus.dspFAUST源文件开始,可以使用以下函数,以参数形式接受:wasm文件名、WebAudio上下文、缓冲区大小和用于扩展WebAudio节点的回调函数:faust.createkarplus(file, context, bs, cb);假设karplus变量最终包含创建的对象,则可以将用户界面作为JSON描述检索出来:var jd = karplus.getJSON();可以使用以下类型的代码控制WebAudio节点:karplus.connect(context.destination); karplus.setParamValue("/path/to/control",0.5);04.4将JavaScript FAUST编译器嵌入浏览器0由于Emscripten编译器有助于在Web上部署任何C++代码,因此可以使用纯JavaScript和WebAssembly(图8)将FAUST编译器本身与其嵌入式wasm后端一起编译。这是通过将C++ libfaust库编译为lib-faust.js库并与libfaust.wasm文件组合来完成的。定义了一个唯一的低级createWasmCDSPFactoryFromString入口点,使用wasm后端编译DSP源代码,并将模块作为字节数组和辅助JavaScript函数作为字符串生成(图9)。再次使用WebAssembly API和JavaScripteval函数,可以将其部署在JavaScript上下文中。编写了一些额外的粘合代码,以便从JavaScript端,将使用以下代码从DSP源代码创建DSP工厂:faust.createDSPFactory(dsp_code, argv, cb);015实际上计算成本更高16https://webaudio.github.io/web-audio-api/#the-audionode-interface0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂17http://faust.grame.fr/editor18http://faust.grame.fr/faustplayground19http://faustservice.grame.fr7060图9:libfaust.js + wasm动态编译链0这里argv是可能的附加编译参数的数组,cb是用于使用创建的DSP工厂的回调函数。然后可以使用以下代码创建一个完全工作的扩展WebAudio节点作为DSP实例;0faust.createDSPInstance(fact, context, bs, cb);0并且可以使用第4.3节中描述的API进行控制。05个使用案例0使用前面解释的技术,已经尝试了三种不同的用例:0• 编译自包含的可直接使用的Web Audio节点 •使用FAUST静态编译链生成带有Web Audio节点的HTML页面 •使用FAUST动态编译链直接在Web上编程DSP。05.1 使用FAUST编程Web Audio节点0使用faust2wasm脚本可以从DSP源文件生成自包含的可用WebAudio节点,该脚本基本上调用FAUST编译器以针对wasm后端,然后使用通用的JavaScript API将生成的代码包装起来,以便在WebAudio上下文中使用。音频节点被创建和激活。控制参数及其布局的完整JSON描述可用于创建自定义的图形用户界面。然后可以读取和写入控制参数。当以后开发自定义控件或图形用户界面时,必须使用此模型。05.2 在Web上部署FAUST DSP示例0使用faust2webaudiowasm脚本,可以将DSP源文件编译为自包含的可运行HTML页面,并将生成的wasm/JavaScript代码包装在基于HTML CSS/SVG的图形用户界面中(图10)。05.3 Web嵌入式编译器0将FAUST编译器本身作为浏览器库打开了有趣的功能,可以在两个不同的工具中进行实验。05.3.1FAUST编辑器。FAUST编辑器应用程序17可用于从任何最新的支持WebAssembly的Web浏览器中编辑、编译和运行FAUST代码(图11)。该编辑器完全在客户端上工作,因此在具有许多同时用户的情况下非常方便(研讨会、课堂等)。它嵌入了具有wasm后端的最新版本FAUST编译器,并提供多音MIDI支持。编辑器引擎基于codemirror。它提供语法高亮、自动完成和直接访问在线文档。0图10:加载wasm模块的自包含HTML页面0图11:FAUST编辑器在线工具0完全在客户端上工作,因此在具有许多同时用户的情况下非常方便(研讨会、课堂等)。它嵌入了具有wasm后端的最新版本FAUST编译器,并提供多音MIDI支持。编辑器引擎基于codemirror。它提供语法高亮、自动完成和直接访问在线文档。05.3.2 FaustPlayground。FaustPlayground应用程序180通过以图形方式连接以FAUST编写的高级模块,用户可以使用FAUST编辑器应用程序以图形方式开发音频应用程序。源代码可以作为字符串、文件或WebURL拖放,或从平台中包含的预定义模块库中加载(图12)。使用libfaust.js,在客户端机器上在浏览器中编译DSP,以成为可连接到其他节点的功能性WebAudio节点。可以随时编辑和重新编译节点源代码。然后,用户可以将其作品导出到在线编译服务支持的所有平台,包括纯独立应用程序、各种插件格式(VST、Max/MSP等)、源代码形式的项目(JUCE、iOS等)19。为了执行此导出,首先必须将图形转换为通过收集图的每个节点的FAUST实现而获得的单个FAUST源代码[4]。0论文:Web编程WWW 2018,2018年4月23日至27日,法国里昂7070图12:FaustPlayground动态编译平台06 基准测试 6.1 比较FAUST C++、LLVMIR和wast/wasm后端0WebAssembly方法承诺将使用Em-scripten工具链将C/C++编写的代码编译为WebAssembly,以实现接近本地的性能。其他语言如Rust(使用mir2wasm工具)则尝试直接生成WebAssembly。随着WebAssembly规范及其实现的稳定,越来越多的语言将直接生成wasm以在浏览器中部署。在编译链的每个步骤中,代码生成质量的问题将迅速出现。由于我们的编译器为专注于音频领域的代码生成,该领域以大量的内存访问和数学运算为特点,我们可能期望生成高质量的代码,甚至在某些情况下超过基于Emscripten生成的通用代码。虽然WebAssembly最初设计用于在Web上运行,但它也可以部署在非Web环境(如nodejs21)或独立的虚拟机(如用C++开发的WAVM),后者使用LLVM技术将WebAssembly即时编译为本机代码。因此,WebAssembly成为一种可在各种情况下使用的便携式二进制格式。这对于像FAUST这样的DSL语言尤其有意义。06.2 C++、LLVMIR和wast/wasm生成代码的基准测试0由于FAUST已经生成C++或LLVMIR代码,因此可以将这两个后端与新的wasm后端进行比较。使用WAVMC++编写的机器可以部署相同的测量代码23。第一个基准测试比较了在MacBook Pro 2.2 GHz Core I7上运行一组DSP的C++、LLVMIR和wasm后端的速度,使用的操作系统是OSX ElCapitan。三个后端都使用了相同的LLVM工具链4.0版本。C++和LLVMIR代码使用了-Ofast优化标志,WAVM运行时是标准版本(没有任何特定的音频优化,稍后会介绍)(图13)。图表清楚地显示,wasm代码仍然比C++或LLVM IR代码慢,但速度差距并不大。020 https://github.com/brson/mir2wasm 21http://webassembly.org/docs/non-web/ 22https://github.com/AndrewScheidecker/WAVM 23http://faust.grame.fr/news/2017/04/26/optimizing-compilation-parameters.html0图13:一组DSP的MBytes/sec(数值越大越好)0在大多数情况下,需要更详细地分析一些DSP的性能问题。06.3 优化用于音频代码的WAVM运行时0WAVM运行时严格遵守WebAssembly规范,因此作为一个有趣的基准参考。在音频领域,C/C++生成的代码通常使用特定的优化标志进行编译24。由于C++WAVM运行时可以很容易地修改,我们对参考实现进行了几处改进,以提高生成的代码性能(图14)。0•移除所有添加到通过所有规范WebAssembly测试的加载/存储25的原子标志• 添加等效的-fast-math编译标志,必须在LLVMIR和JIT(本机)26生成步骤中完成•最后,简化一些数学运算符,使用它们的标准定义27而不是严格实现WebAssembly官方语义的特定WAVM编码的定义28(例如,查看f32.min/f32.max操作的定义及其对NaN值的处理)0该图表显示了严格遵守WebAssembly规范的运行时与针对音频代码进行优化的相同运行时之间的差异。这在某种程度上表征了C++或LLVMIR版本的FAUST生成代码与wasm生成代码之间始终存在的不可压缩的速度差异。请注意,在生成LLVMIR代码之后,WAVM运行时会运行一组LLVMIR到IR的优化传递。还需要测试是否添加更多优化传递(特别是自动向量化传递)可以帮助生成更好的代码。024像-fast-math一样,它允许编译器生成更快(但不太精确)的数学运算25https://github.com/sletz/WAVM/commit/cf6011026aa75dfd0f88e051da271ce0c0d525a9 26https://github.com/sletz/WAVM/commit/1aa96a2088ed1c6eb918b7f292f4571aecdfc6da 27https://github.com/sletz/WAVM/commit/a9e2a91c53e79168fb7e193beb36e99d81d0be21 28http://webassembly.org/docs/semantics/0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂7080图140图1506.4 使用Binaryen进行模块优化0Binaryen是一个用于WebAssembly的编译器和工具链基础设施库29,用C++编写。它包含了wasm到wasm的优化传递,可能可以进一步提高FAUST生成的wasm代码的速度。我们在FAUST生成的wasm模块上使用-wasm-opt工具进行了-O3级别的测试,以估计我们可以期望的加速比。该图表显示了有限的增益,在一些测试案例中不超过5%(图15)。06.5浮点非规格化处理0可以在WAVM机器30中轻松测试软件浮点非规格化代码。这是使用-ftz从0到2生成的代码的结果(图16)。当激活软件FTZ时,代码连续变慢一点,显然是为了避免在存在非规格化值时CPU消耗急剧增加的病态情况。-ftz 2模式似乎是最有效的,并且将优先使用。0通过在本机运行的CPU上明确禁用硬件FTZ模式,可以在WAVM机器30中轻松测试软件浮点非规格化代码。这是使用-ftz从0到2生成的代码的结果(图16)。当激活软件FTZ时,代码连续变慢一点,显然是为了避免在存在非规格化值时CPU消耗急剧增加的病态情况。-ftz 2模式似乎是最有效的,并且将优先使用。0图160图1706.6 Emscripten与FAUST直接编译对比0由FAUSTwasm后端直接生成的Wasm代码可以与通过编译(使用Emscripten)FAUSTC后端生成的wasm代码进行比较。所有复杂的优化(例如基于LLVM的Emscripten编译器上的优化)都可以在C端使用,这是一个更简单的FIR到wasm生成模型,但与直接wasm端上的一些特定优化(例如第4.2.2节中描述的优化内存布局)相结合。使用-sSIDE_MODULE=1模式对FAUST生成的C进行编译,以生成一个轻量级的wasm模块,不包含任何运行时,由额外的JavaScript粘合代码加载和激活。在FirefoxNightly下完成,图表显示直接wasm代码生成甚至可以击败Emscripten生成的wasm代码(图17)。06.7比较三个浏览器0准备了31个HTML测试页面,以比较三个主要浏览器的性能。DSP代码使用浮点非规格化保护进行编译。生成的wasm模块的计算031 http://faust.grame.fr/bench/0Track: Web Programming WWW 2018, 2018年4月23日至27日,法国里昂[1] John Backus. Can Programming Be Liberated from the von Neumann Style ?ACM Turing Award lecture, pages 613–641, 1978.[2] C. Clark and A. Tindale. Flocking: a framework for declarative music-making onthe Web. In Proceedings of the International Computer Music Conference, 2014.[3] Sarah Denoux, Stéphane Letz, Yann Orlarey, and Dominique Fober. FAUSTLIVE,Just-In-Time Faust Compiler... and much more. In Proceedings of the Linux AudioConference 2014, ZKM, Karlsruhe, Germany, 2014.[4] Sarah Denoux, Yann Orlarey, Stéphane Letz, and Dominique Fober. Calcul d’uneexpression Faust équivalente à partir d’un graphe d’applications. In Journéesd’Informatique Musicale, 2016.[5] V. Lazzarini, E. Costello, S. Yi, and J. Fitch. Csound on the Web. In Proceedings ofthe Linux Audio Conference, 2014.[6] S. Letz, Y. Orlarey, and D. Fober. Comment embarquer le compilateur Faust dansvos applications? In In Proceedings of the Journees d’Informatique Musicale, 2013.[7] Yann Orlarey, Dominique Fober, and Stephane Letz. An algebra for block dia-gram languages. In ICMA, editor, Proceedings of International Computer MusicConference, pages 542–547, 2002.[8] Yann Orlarey, Dominique Fober, and Stephane Letz. Syntactical and SemanticalAspects of Faust. Soft Computing, 8(9):623–632, 2004.[9] Yann Orlarey, Dominique Fober, and Stephane Letz. Parallelization of audioapplications with Faust. In Proc. of the 6th Sound and
下载后可阅读完整内容,剩余1页未读,立即下载







安全验证
文档复制为VIP权益,开通VIP直接复制
