没有合适的资源?快使用搜索试试~ 我知道了~
探索在高性能计算中使用WebAssembly
920探索在HPC中使用WebAssembly0Mohak Chadha,Nils Krueger,JophinJohn,Anshul Jindal,MichaelGerndt计算机体系结构和并行系统主席,德国慕尼黑工业大学。0ShajulinBenedict计算机科学与工程系,印度信息技术科大学Kottayam,喀拉拉邦。0基于Linux内核提供的命名空间的容器化方法在HPC社区中越来越受欢迎,既可以用于隔离应用程序,又可以用作打包和分发应用程序的格式。然而,它们在HPC系统中的采用和使用面临着几个挑战。其中包括在HPC资源上直接以非特权方式运行和构建科学应用程序容器镜像的困难,HPC架构的日益异构性,以及仅在HPC系统上可用的专用网络库的访问。基于容器的HPC应用程序开发的这些挑战与一种名为WebAssembly(Wasm)的新型通用中间二进制格式所提供的几个优势密切相关。其中包括轻量级用户空间隔离机制和在操作系统和处理器架构之间的可移植性。在本文中,我们探索了将Wasm用作基于MPI的HPC应用程序的分发格式。为此,我们提出了一种名为MPIWasm的新颖的用于基于MPI的HPC应用程序的Wasm嵌入器,它能够实现Wasm代码的高性能执行,对MPI调用的开销很低,并支持HPC系统上存在的高性能网络互连。我们使用标准HPC基准测试在一台生产HPC系统和AWSGraviton2节点上评估了MPIWasm的性能和开销。我们实验的结果表明,MPIWasm在所有场景下都具有竞争力的本机应用程序性能。此外,我们观察到与不同的标准化基准测试的静态链接二进制文件相比,Wasm二进制文件平均减小了139.5倍。0CCS概念:•软件及其工程→流程管理。0关键词:WebAssembly,Wasmer,Wasm,MPI,HPC0获得许可者可以免费制作或分发个人或课堂使用的本作品的全部或部分数字或纸质副本,但不能以牟利或商业优势为目的制作或分发副本,并且副本必须带有本通知和第一页的完整引用。除ACM拥有的本作品组成部分之外,必须尊重他人拥有的版权。允许带有信用的摘要。复制,再出版,发布服务器或重新分发列表需要事先获得特定的许可和/或费用。请向permissions@acm.org申请权限。PPoPP ’23,2023年2月25日至3月1日,加拿大蒙特利尔,版权所有2023年计算机协会。ACM ISBN979-8-4007-0015-6/23/02...15.00美元https://doi.org/10.1145/3572848.35774360ACM参考格式:Mohak Chadha,Nils Krueger,JophinJohn,Anshul Jindal,Michael Gerndt和ShajulinBenedict。2023年。在第28届ACMSIGPLAN年度并行编程原理和实践研讨会(PPoPP’23)上探索在HPC中使用WebAssembly。2023年2月25日至3月1日,加拿大蒙特利尔。ACM,美国纽约,15页。https://doi.org/10.1145/3572848.357743601 引言0由于容器的可移植性和高可用性,它们已成为在云环境中开发、测试和部署各种应用程序的事实标准,从企业到Web服务[29]。这是因为容器使用户能够将其应用程序与其自定义软件依赖项一起作为单个单元打包到易于部署的映像中。在云中受欢迎的背景下,容器也在HPC社区中引起了越来越多的兴趣[30, 74,90]。对于HPC系统,容器为用户提供了灵活性,并允许他们为其大规模科学应用程序定义自定义软件堆栈,即用户定义的软件堆栈(UDSS)。此外,它们还可以提供易于使用、可靠且可验证的环境,以便在未来进行复现。为此,引入了几个面向HPC的容器化解决方案,例如Charliecloud [72],Shifter [49],Singularity [58],Podman[48]和Sarus[33]。与以往的方法相比,本文研究了一种名为WebAssembly(Wasm)[52]的新技术,被称为Linux容器的替代品[81],用于打包和分发HPC应用程序。尽管容器的使用越来越普遍,但在HPC系统中采用和使用容器仍然受到严格限制[36]。这可以归因于用户在HPC系统上运行和构建容器映像的过程中常遇到的几个挑战。对于执行容器,大多数容器化解决方案都需要root权限,而正常的HPC用户由于共享文件系统和UNIX权限而无法获得root权限。虽然HPC专注的容器化解决方案(如Singularity[58]和Podman [48])通过fakeroot[61]支持无root容器,但它们目前的实现不支持常见于HPC系统上的GPFS等分布式文件系统[70,80]。此外,正如[71]所提到的,使用非特权(普通)用户在HPC资源上构建符合OpenContainerInitiative(OCI)[69]规范的容器映像是非常困难的,需要超级计算中心的支持。这是因为大多数容器构建解决方案,如Docker[43]也需要root权限。因此,大多数用户使用自己的本地系统构建/开发其应用程序容器映像,然后将构建好的映像传输到HPC系统的登录/前端节点上进行执行。然而,这种情况会导致基于容器的HPC应用程序开发中出现多个问题。首先,HPC节点变得越来越异构化[12],具有不同的处理器架构,如x86_64或aarch64,并且具有特殊的加速器,如GPU。由于应用程序性能在HPC中至关重要,使用特定处理器的特定微体系结构特性编译应用程序非常重要。通过交叉编译HPC应用程序或使用QEMU进行仿真构建多个平台的容器映像是可能的,例如使用build-x[44]等插件,但它在HPC应用程序构建过程中得不到广泛支持,需要具体的Linux内核功能(binfmt_misc[62])。此外,测试和开发HPC应用程序仅提供目标系统上的洞察力。此外,大多数容器映像的大小可以从几个MiB到几个GiB不等。因此,从本地系统频繁传输到HPC系统可能很麻烦。其次,构建HPC应用程序需要访问专用网络库和编译器许可证,这些许可证在本地用户系统上不可用。最后,尽管不同的容器化解决方案对容器化应用程序的性能几乎没有影响[72, 75,84],但构建高性能的HPC应用程序容器映像并不简单,需要陡峭的学习曲线,并需要了解特定MPI库版本(例如OpenMPI [10]4.0)和目标系统上存在的高性能网络互连硬件(例如Intel OmniPath[4])和库(例如英特尔性能缩放消息传递[5])。容器化HPC应用程序的这些挑战与WebAssembly[52]旨在解决的几个优势和核心问题密切相关。Wasm是一种低级别的、静态类型的通用二进制指令格式,用于在虚拟机中进行内存安全的隔离执行。它提供了对现代处理器架构和操作系统的可移植性、快速执行和低级别内存模型的支持[52]。尽管最初是为在Web浏览器中执行而设计的,但由于其简单性和通用性,Wasm在非Web领域(如无服务器计算[78]、边缘计算[47,53]和物联网[51])中得到广泛采用和使用。它不需要垃圾回收,并且被设计为具有对LLVM [59]前端(如C、C ++、C#和Rust [32, 35, 40, 45,77])支持成熟的编程语言的通用编译目标。图1演示了在HPC中使用Wasm的一般工作流程。开发人员可以预先在其本地系统上将其HPC应用程序编译为Wasm,并将其分发到多个平台,而不是分发源代码或构建应用程序容器。通常,与本机应用程序相比,Wasm二进制文件的大小较小930PPoPP ’23, 2023年2月25日至3月1日,加拿大蒙特利尔,Mohak Chadha等人。0图1。HPC应用程序可以编译为WebAssembly,并分发到多个平台,在支持WebAssembly嵌入程序的情况下高效执行。0x86_64二进制文件[52,56,91]。在此之后,可以使用独立的Wasm嵌入程序[52]在任何平台上执行生成的二进制文件。Wasm嵌入程序有两个主要目的。首先,它为在平台上运行Wasm二进制文件提供了一个隔离的执行环境。与利用不同的Linux命名空间[71]进行隔离和安全性的基于容器的方法不同,Wasm基于软件故障隔离(SFI)[85]和控制流完整性(§2.2)提供了轻量级的应用级隔离。其次,它负责将Wasm二进制文件编译为本机机器代码,要么通过在执行时使用即时(JIT)引擎,要么通过使用相同的JIT引擎或AOT编译器进行AOT。请注意,Wasm二进制文件可以由普通用户执行,并且完全没有特权。目前有几个开源独立的嵌入程序,如Wasmer[87]、Wasmtime [37]和Wasm3[79]。然而,它们都不支持执行HPC应用程序。作为将Wasm引入HPC生态系统的第一步,我们在本文中仅关注基于MPI的[6]HPC应用程序。我们之所以选择MPI,是因为它在HPC社区中有着广泛的认知和影响力[34]。为此,我们的主要贡献是:0•我们实现并展示了MPIWasm,这是一个基于Wasmer[87]的面向MPI的HPC应用程序的新型Wasm嵌入程序。MPIWasm通过零拷贝内存操作在MPI调用中具有低延迟,支持Intel OmniPath [4]等高性能网络互连。0•我们通过广泛的实验证明了MPIWasm的低开销和性能,在生产HPC系统和基于x86_64和aarch64体系结构的AWS Graviton2[1]节点上使用标准化的HPC基准进行了测试。0•我们详细阐述了在HPC生态系统中使用Wasm的不同可能的未来方向。0本文的其余部分结构如下。§2提供了关于Wasm的详细概述。在§3中,我们详细描述了我们的嵌入程序MPIWasm。我们的实验结果在§4中呈现。在§5中,我们描述了在HPC生态系统中使用Wasm的不同可能方向。§6描述了一些2...4...8...19...940探索在HPC中使用WebAssembly PPoPP'23,2023年2月25日至3月1日,加拿大蒙特利尔01(type(;1;)(func(param i32)(result i32)))03(type(;5;)(func(param i32 i32)(result i32)))05(type(;14;)(func(param i32 i32 i32 i32 i32 i32)06(result i32))07(type(;15;)(func(param i32 i32 i32 i32)(result i32)))09(import"wasi_snapshot_preview1""path_open"010(func $__wasi_path_open(type 22))011(import"wasi_snapshot_preview1""fd_close"012(func $__wasi_fd_close(type 1))013(import"wasi_snapshot_preview1""fd_seek"014(func $__wasi_fd_seek(type 23))015(import"wasi_snapshot_preview1""fd_read"016(func $__wasi_fd_read(type 15))017(import"wasi_snapshot_preview1""proc_exit"018(func $__wasi_proc_exit(type 0))020(export"_start"(func$_start))021(导出"memory"(memory 0))0清单1。使用WASI-SDK在WebAssembly文本格式(WAT)[68]中以示例形式表示编译的C++应用程序的Wasm模块。省略号表示省略的部分。0我们的工作与之前的方法相关。在第7节中,我们总结了本文并展望了未来。02 WebAssembly简介02.1 WebAssembly概述WebAssembly(Wasm)于2015年作为用于基于Web浏览器的应用程序的JavaScript的替代品引入。它取代了Mozilla之前的尝试asm.js[67],asm.js专注于可以进行AOT优化的JavaScript代码的子集。当将应用程序编译为Wasm时,生成的二进制文件称为模块。Wasm模块包含函数定义、全局变量的声明、表和线性内存地址空间。Wasm中的所有应用程序代码都组织在函数中。Wasm中的概念性机器是基于堆栈的,并且不包含寄存器,因此所有指令都从机器的堆栈中弹出操作数。然而,由于应用程序控制流是模块的显式部分,并且Wasm操作是类型化的,因此可以在程序的任何点上静态预测堆栈的布局,这允许编译器将堆栈语义转换为基于寄存器的指令集。与其他高级编程语言类似,Wasm允许定义不在特定函数或块范围内的全局变量。Wasm模块中的表用于存储对函数的引用[52]。WasmISA目前仅支持四种变量的数据类型:(i)i32,32位整数,(ii)i64,64位整数,(iii)f32,32位IEEE754浮点数,(iv)f64,64位IEEE754浮点数。为了构造复杂类型,通常使用这些基本类型的组合。Wasm通过导入/导出系统提供了数据和代码在模块和嵌入程序之间共享的能力。所有可以出现在Wasm模块中的函数定义都可以从嵌入程序中导入,而不是在其中定义。同样,可以导出模块中的函数定义,以便嵌入程序可以利用它们(§2.3)。0模块中存在的函数可以导出,以便嵌入程序可以利用它们(§2.3)。02.2 WebAssembly安全性和沙箱模型Wasm使用软件故障隔离技术(SFI)[85]来隔离执行的Wasm模块。默认情况下,Wasm模块不能与主机系统交互或执行任何类型的I/O操作。Wasm模块的代码要发起的任何系统交互必须通过从嵌入程序导入的函数来完成(§2.1)。因此,嵌入程序可以充当翻译层和仲裁者,以强制执行隔离要求。作为翻译器,嵌入程序可以为Wasm模块提供通用接口,即使底层系统可能具有不同的本机接口,而作为仲裁者,嵌入程序可以根据应用级安全策略限制Wasm模块对系统资源的访问。例如,嵌入程序可以仅允许文件I/O访问位于特定目录中的文件,以使Wasm模块与文件系统的其余部分隔离。虽然从原理上讲与Linux上的Seccomp-BPF[83]等内核级系统调用过滤技术类似,但在应用程序级别上执行此类过滤可以定义语义更有意义的策略。在Wasm中,所有内存访问都限于模块的线性内存,该内存与代码空间分离。目前,Wasm规范[52]支持32位地址来索引模块可以访问的内存。虽然这限制了单个模块的内存为4GiB,但它还可以在运行时对内存访问进行硬件加速的边界检查[42]。如果嵌入程序是一个具有64位内存地址空间的进程,它可以在其内存空间中安全地执行不受信任的Wasm模块,而无需通过保留连续的虚拟内存范围来进行额外的隔离,供模块使用。此范围中的并非所有页面都需要映射到物理内存,只需映射所需数量的页面以适应模块在给定时间点使用的内存量。这确保了Wasm模块只能在其自己的执行环境中运行,而不能破坏嵌入程序的内存,因为任何越界内存访问都将导致页面故障,然后可以由嵌入程序处理。此外,由于Wasm规范中的内存指令使用偏移量,因此不可能在Wasm中读取和写入任意内存位置。在由C程序生成的汇编中,函数调用被表示为跳转指令到函数的第一条指令的地址,典型的攻击是将此地址更改为控制程序的控制流的地址。但是,使用Wasm是不可能的,因为它通过强制实施结构化程序控制流来实现控制流完整性。这是由于两个原因。首先,在Wasm中,函数被表示为表中的索引(§2.1),这增加了额外的间接级别以表示函数地址。其次,Wasm规范防止...3...9);13);3))7))11))950PPoPP '23,2023年2月25日至3月1日,加拿大蒙特利尔Mohak Chadha等人01 typedef int MPI_Comm;02 typedef int MPI_Datatype;04 int MPI_Init(int * argc,char *** argv);05 int MPI_Finalize(void);06 int MPI_Send(07 const void * buf,int count,MPI_Datatype datatype,08 int dest,int tag,MPI_Comm comm010 int MPI_Recv(011 void * buf,int count,MPI_Datatype datatype,012 int source,int tag,MPI_Comm comm,MPI_Status * status0清单2。自定义MPIWasm mpi.h头文件的摘录。01(导入"env" "MPI_Init"(02 func $MPI_Init(参数i32 i32)(结果i32)04(导入"env" "MPI_Finalize"(func $MPI_Finalize(结果i32)))05(导入"env" "MPI_Send"(06 func $MPI_Send(参数i32 i32 i32 i32 i32 i32)(结果i32)08(导入"env" "MPI_Recv"(09 func $MPI_Recv(参数i32 i32 i32 i32 i32 i32 i32)010(结果i32)0清单3。与列出的函数相对应的模块导入的WAT表示。0构建任意内存地址[42]以及嵌入器和模块内存之间的分离防止覆盖函数指令。02.3 WebAssembly系统接口0由于WebAssembly最初是为Web浏览器设计的,因此针对POSIX环境并在其上执行Wasm模块的系统接口不是原始规范的一部分[52]。为了克服这个问题,设计了WebAssembly系统接口(WASI)规范[89]。WASI指定了一个嵌入器需要实现的接口,以执行大多数POSIX应用程序。实现WASI规范的嵌入器将能够运行使用WASI-SDK[28]编译的任何通用应用程序。WASI-SDK包括clang编译器及其基于musllibc的自己的C库,这些库调用从嵌入器中导入的WASI系统调用,而不依赖于Linux系统调用[22]。请注意,由于Linux系统上广泛使用的glibc[26],某些应用程序已经依赖于glibc特定的功能或行为。这些应用程序在编译为符合WASI标准的Wasm模块之前需要进行修改。清单1显示了使用WASIP-SDK(§3.3)在WebAssembly文本格式(WAT)中显示的C++应用程序的编译后的Wasm模块。WAT是一种人类可读的格式,使开发人员可以检查Wasm模块的源代码。可以观察到模块包含多个以整数为参数和返回类型的函数(第1-7行)(§2.1),导入WASI函数(第9-18行),并导出其_start(主函数)和内存(第20-21行)。导出这两个定义允许执行此模块的嵌入器调用其入口点函数,并读取和写入模块的线性内存。而第9-16行的导入语句使得Wasm模块能够打开并从文件中读取0当一个应用程序打算从文件中读取数据时,函数proc_exit被嵌入器用于处理应用程序的终止,例如,通过解除为模块保留的内存来处理。为了使模块执行,导入的函数需要由嵌入器实现。03MPIWasm在本节中,我们详细描述了MPIWasm,我们的嵌入器,用于执行利用MPI标准函数的Wasm模块。03.1 概述0MPIWasm的目的是支持在HPC系统上编译为Wasm的MPI应用程序的执行。为了促进其在HPC环境中的采用和适用性,它(i)支持将编译为Wasm的MPI基于HPC应用程序的高性能执行(§3.3),(ii)通过零拷贝内存操作降低MPI调用的开销(§3.6),以及(iii)支持高性能互连,如Infiniband[64]和Intel OmniPath[4]。这些网络互连被HPC系统上的MPI库用于高性能的等级间通信。为了在现代HPC系统上立即支持网络互连,MPIWasm在运行时链接到目标HPC系统上的MPI库,并在Wasm模块和主机1MPI库之间提供翻译层。因此,开发人员无需了解目标HPC系统上特定的网络库或网络互连。根据特定的主机MPI库,如OpenMPI [10]或MPICH[8],需要单独构建MPIWasm。这两个库目前由MPIWasm支持。我们的嵌入器目前支持用C/C++编写并符合MPI-2.2标准的MPI应用程序。未来我们有兴趣将对MPI-3.1的支持整合进来,但这不在本文的范围之内。我们选择关注C/C++应用程序,是因为LLVM/Clang[59]项目中的Wasm后端自llvm-8以来具有稳定性和成熟性。作为MPIWasm的基础,我们使用了名为Wasmer[87]的开源Wasm嵌入器。Wasmer支持在Linux、Windows和macOS三个主要平台上执行Wasm模块,并支持x86_64和aarch64指令集架构。此外,它实现了WASI规范(§2.3)并提供了定义为模块提供的其他函数的人性化机制。这种嵌入器功能的动态扩展使得可以将MPI函数添加到其提供给Wasm模块的功能中。为了实现MPIWasm,我们使用了Rust编程语言。这是由于两个原因。首先,它提供了与C/C++相当的高性能和内存安全性[82]。01 我们将目标和主机这两个术语互换地用于执行Wasm模块的系统。960探索在HPC中使用WebAssembly PPoPP '23,2023年2月25日至3月1日,加拿大蒙特利尔0表1. 比较Wasmer [87]支持的不同编译器后端在HPCG [73]Wasm模块中的编译持续时间和性能。该Wasm模块使用我们的WASI-SDK(§3.3)生成。该Wasm模块在x86_64系统上使用MPIWasm执行。0编译器编译持续时间(毫秒)单核性能(GFLOP/s)0Singlepass [86] 52 0.37690Cranelift [3] 150 1.32400LLVM [59] 2811 1.54260其次,它广泛支持和文档化了嵌入Wasmer并将其用作库的方法。03.2 将C/C++MPI应用程序编译为Wasm大多数MPI应用程序都希望其执行环境中可用POSIX功能,例如读取和写入文件描述符。WASI(§2.3)定义了WebAssembly导出,使得针对其的Wasm模块能够调用POSIX系统上C标准库中定义的大多数函数。为此,WASI-SDK [28]结合了clang编译器和wasi-libcC库,使得只使用POSIX函数而不需要其他库的C/C++应用程序能够编译为Wasm。WASI-SDK不支持编译C/C++MPI应用程序。因此,我们实现了一个自定义的mpi.hMPI头文件,并将其添加到WASI-SDK中。该头文件包括不同MPI类型的定义,如MPI_Op,MPI_Comm和MPI_Datatype,以及MPI_Status结构的定义。此外,它根据MPI-2.2[65]标准为MPI函数定义了签名。清单2显示了该头文件的摘录,它是在MPI库中找到的传统头文件的简化版本,其中大多数类型定义为整数(§3.6)。通过将我们的头文件与WASI-SDK结合使用,符合MPI-2.2标准的C/C++MPI应用程序可以编译为Wasm。此外,为了简化整个MPI应用程序的编译过程并促进使用,我们实现了一个基于Python的自定义工具。清单3显示了Wasm模块中存在的与列出的函数相对应的不同MPI特定的导入。MPIWasm提供了这些导入的定义,以便执行基于MPI的HPC应用程序。此外,它支持WASI规范,该规范为MPI应用程序提供了POSIX功能。03.3 以高性能执行Wasm代码 有几种执行Wasm模块的策略。其中包括使用解释器[79],提前编译(AoT) [37],或即时编译(JIT)[37]。然而,对于HPC系统来说,最有用的方法是在应用程序执行之前将Wasm指令(WasmISA)转换为宿主机器的本机指令集,即AoT。MPIwasm在此基础上构建,利用了Wasmer提供的代码生成基础设施[87]。Wasmer目前支持三个编译器后端,即Singlepass[86],Cranelift[3]和LLVM[59]。SinglePass编译器设计为在线性时间内生成机器代码,并且不执行许多代码优化。Cranelift编译器完全基于Rust,并类似于LLVM。使用Cranelift,首先将WASM指令转换为Cranelift的中间表示(IR),即( Cranelift-IR),然后考虑到特定微架构的优化将其转换为宿主机器的本机指令集。另一方面,使用LLVM,首先将WasmISA转换为LLVM-IR,然后生成本机机器代码。Cranelift-IR类似于LLVM-IR,但在较低的抽象级别上,这妨碍了中级代码优化2。在编译过程结束时,这三个编译器都会生成一个共享对象,可以使用libloading库的快速dlopen调用加载该对象[27]。表1显示了Wasmer为HPCG基准测试支持的三种不同编译器的编译时间和运行时间性能的比较。虽然LLVM编译Wasm模块的速度最慢,但对于HPCG应用程序来说,它也产生了最快的运行时性能。因此,我们选择LLVM作为MPIWasm中的编译器后端。为了抵消与其他两个编译器相比,LLVM所需的较长编译时间,我们为生成的机器代码实现了缓存机制。我们的缓存机制建立在Wasmer提供的FileSystemCache[46]上。在我们的实现中,我们使用Blake-3哈希函数[2]为每个Wasm模块生成哈希。此外,我们将LLVM生成的共享对象存储为本地文件系统中的生成哈希。因此,对Wasm模块的任何更改都会导致生成新的哈希,从而触发对模块的重新编译。因此,在使用MPIWasm的系统上重复执行相同的应用程序不会导致执行的重新编译开销。03.4 使用MPIWasm进行文件系统隔离0由于在Wasm中,应用程序的所有系统交互都必须通过调用嵌入器实现的函数来执行(§2.2 ,§2.3),因此它使得嵌入器能够对其使用进行附加限制,并对所提供的参数进行检查。在Wasmer中,处理文件I/O的所有导出函数都执行自己的权限处理,与操作系统使用的权限处理分开。这种进程内文件系统访问的间接性允许Wasmer向Wasm模块呈现虚拟目录树,该树仅包含模块允许访问的目录。此外,对各个目录的访问权限可以比执行嵌入器的用户被授予的权限更加限制性。例如,用户可以对其主目录及其所有子目录具有读写访问权限,但可以仅对一个特定子目录授予Wasm模块只读访问权限。MPIWasm使用-d标志向Wasm模块授予对给定目录的读写访问权限。请注意,对于暴露的目录,不会向Wasm模块呈现完整的绝对路径。在呈现给Wasm模块的虚拟目录树中,它被给予访问权限的所有子目录都是根目录的直接子目录。这种映射目录路径的方法避免了将目录的完整路径暴露给Wasm模块中包含的信息,例如在主目录的情况下的用户名。02 关于Cranelift-IR和LLVM-IR的更详细讨论可以在这里找到[25]。970PPoPP ’23, 2023年2月25日至3月1日,加拿大蒙特利尔 Mohak Chadha等人0图2.MPIWasm的内存地址空间与已实例化的Wasm模块。所有对Wasm模块线性地址空间的内存访问指令都相对于基地址给出了偏移量。0Wasm中的所有应用程序的系统交互都必须通过调用嵌入器实现的函数来执行(§2.2 ,§2.3),因此它使得嵌入器能够对其使用进行附加限制,并对所提供的参数进行检查。在Wasmer中,处理文件I/O的所有导出函数都执行自己的权限处理,与操作系统使用的权限处理分开。这种进程内文件系统访问的间接性允许Wasmer向Wasm模块呈现虚拟目录树,该树仅包含模块允许访问的目录。此外,对各个目录的访问权限可以比执行嵌入器的用户被授予的权限更加限制性。例如,用户可以对其主目录及其所有子目录具有读写访问权限,但可以仅对一个特定子目录授予Wasm模块只读访问权限。MPIWasm使用-d标志向Wasm模块授予对给定目录的读写访问权限。请注意,对于暴露的目录,不会向Wasm模块呈现完整的绝对路径。在呈现给Wasm模块的虚拟目录树中,它被给予访问权限的所有子目录都是根目录的直接子目录。这种映射目录路径的方法避免了将目录的完整路径暴露给Wasm模块中包含的信息,例如在主目录的情况下的用户名。03.5 从Wasm翻译到宿主内存地址Wasm安全模型的一个重要部分是宿主和模块的线性内存地址空间的分离(§2.2)。由于保护数据结构免受模块代码的意外或恶意访问是Wasm嵌入器的责任,所以这种分离对于支持MPI应用程序来说是一个挑战,因为MPIAPI是基于库能够直接读写应用程序的内存。执行的基于Wasm的MPI应用程序只能提供自己线性内存地址空间中的内存地址,而目标MPI库需要宿主内存地址空间中的地址。对于执行Wasm模块,MPIWasm为Wasm模块使用了自己地址空间的一部分。因此,该范围内的每个字节既可以使用模块的内存空间中的内存地址进行寻址,也可以使用嵌入器(宿主)的内存空间中的内存地址进行寻址。此外,在实例化模块的线性内存时,MPIWasm记录了它的基地址。在此之后,可以将来自Wasm模块的线性地址空间的地址转换为嵌入器的地址空间,反之亦然,方法是将线性地址空间中的地址视为相对于模块基地址的偏移量。如图2所示。特别地,MPIWasm直接将指向模块线性地址空间的32位Wasm指针转换为指向嵌入器地址空间的64位指针,反之亦然。为此,MPIWasm直接利用了宿主系统上的MPI库,而不复制任何数据。0将数据从模块的地址空间复制到其他位置,即它支持零拷贝内存操作。03.6 翻译MPI数据类型0MPI是一个作为库实现的通用接口,最常见的实现是OpenMPI [10]、MPICH [8]和MVAPICH[9]。因此,它不保证应用程序二进制接口(ABI)和库之间的互操作性。这意味着更改MPI实现需要重新编译整个应用程序代码。ABI不兼容的原因之一是,MPI标准没有明确指定MPI_Op等数据类型的显式类型,它们的实现完全取决于MPI库。然而,由于Wasm模块被设计为可在不同的MPI库和不同的CPU架构之间进行移植,因此有必要在主机的MPI库使用的数据类型和MPIWasm向Wasm模块公开的数据类型之间添加一个抽象层。抽象是可能的,因为大多数MPI数据类型,如MPI_Comm、MPI_Datatype和MPI_Op,对于应用程序来说是不透明的,只被用作MPI函数的参数。MPIWasm将大多数MPI数据类型定义为Wasm模块的32位整数(列表2),并将这些数据类型透明地转换为主机等价物(§3.7)。我们使用整数作为数据类型,因为MPIWasm在内部使用ID来标识其代表模块创建的数据结构,以便与主机MPI库进行通信。03.7在MPIWasm中实现MPI函数Wasm导入按照命名空间和要导入的定义的名称进行引用。默认情况下,将C/C++应用程序编译为Wasm时未定义的任何符号都将通过将其作为模块中的env命名空间的导入来解析。这在清单3中通过与MPI标准相关的函数导入来示例。MPIWasm为所有这些函数提供了与原始MPI函数相同名称的定义,并在env命名空间中导出它们。为了实现这些函数,我们结合了内存地址和MPI数据类型的转换,如§ 3.5和§3.6中所述。为此,我们维护一个名为Env的结构,它存储这些转换所需的全局状态。此结构包括有关分配给Wasm模块的内存的信息,它的基指针(§3.5)以及由模块使用的不同数据类型(例如MPI_Comm)。为了直接使用主机MPI库,我们在MPIWasm中使用项目rsmpi [7]。rsmpi为Rust提供MPI绑定,并支持OpenMPI[10]和MPICH[8]。它利用rust-bindgen项目生成针对特定MPI库的外部函数接口。MPIWasm中的每个MPI函数直接调用rsmpi中的等效函数,并传递适当的参数。对于MPI-2.2标准的大多数函数,MPIWasm直接将执行推迟给了主机MPI库,980探索在HPC中使用WebAssembly PPoPP '23,2023年2月25日至3月1日,加拿大蒙特利尔 Mohak Chadha等。01 mpirun -np <进程数> ./mpiWasm mpi-app.wasm \02 <参数>0清单4。使用MPIWasm执行编译为Wasm的MPI应用程序。0实现MPI函数MPI_Alloc_mem和MPI_Free_mem的方式不同。使用这些函数,可以为其他MPI函数分配内存。当Wasm模块调用MPI_Alloc_mem时,它期望在模块的地址空间中获得一个32位内存地址,而调用主机MPI库的MPI_Alloc_mem函数会返回一个64位内存地址,该地址位于为Wasm模块保留的内存块之外的嵌入者的内存地址空间中。为了克服这个问题,只有当Wasm模块定义和导出了malloc和free函数时,MPIWasm才支持MPI_Alloc_mem和MPI_Free_mem。当调用MPI_Alloc_mem时,MPIWasm简单地调用导出的malloc并接收一个适当的32位模块内存地址。然后,该地址可以用作MPI_Alloc_mem的返回值。我们以类似的方式实现MPI_Free_mem。03.8限制Wasm规范目前假定多字节值的字节顺序为小端[52]。通过直接访问Wasm模块的内存给主机MPI库,我们假设模块地址空间和嵌入地址空间中的字节顺序是相同的。因此,MPIWasm不支持大端CPU架构。这并不是一个缺点,因为HPC系统中的大多数处理器架构都是小端。此外,由于Wasm模块的当前线性32位内存空间,编译为Wasm的HPC应用程序的内存不能超过4GiB。支持64位内存地址是Wasm规范的重要里程碑,并在WasmMemory64提案[20]中强调,但不在本工作的范围内。04 实验结果0在本节中,我们介绍了我们在不同处理器架构下嵌入式MPIWasm的性能结果。对于我们的所有实验,我们遵循报告结果的最佳实践[54]。04.1系统描述为了分析我们实现的Wasm嵌入器的性能,我们使用了两个系统。首先是位于我们研究所的生产HPC集群,即SuperMUC-NG[11]。其次是具有Graviton2处理器[1]的AWSEC2虚拟机(VM)实例。我们的HPC集群包含八个岛屿,共计6480个基于IntelSkylake-SP架构的计算节点。每个计算节点有两个插槽,包括两个Intel Xeon Platinum8174处理器,每个处理器有24个核心,总共有96GiB的主内存。每个核心的名义操作频率为3.10 GHz。超线程和TurboBoost在系统上被禁用。我们系统上的内部互连是由带有100 Gbit/s带宽的快速IntelOmni-Path [4]网络。此外,我们的集群提供了基于Lenovo DSS-G for IBM SpectrumScale [19]的通用并行文件系统,其总带宽为200GiB/s。对于我们的实验,我们使用最多128个HPC系统节点,即6144个核心。另一方面,基于64位ARMv8-A Neoverse-N1 [24]架构的AWSGraviton2处理器每个处理器由32个核心组成,名义频率为2.50GHz,总共有64GiB的主内存。我们将实验限制在Graviton2处理器的一个节点上。0表2。比较不同MPI应用程序的本机动态链接、静态链接和Wasm二进制文件的大小。本机应用程序针对x86_64架构编译。0应用程序 本机动态大小(KiB) 本机静态大小(MiB) Wasm大小(KiB)0Intel MPI基准[55]。1087 27 8930HPCG [73]。164 26 7220IOR [60]。364 16 315.320IS [31]。36 15 57.880DT [31]。40 15 49.510PPoPP '23,2023年2月25日至3月1日,加拿大蒙特利尔Mohak Ch
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 4
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功