0

当我在 WebAssembly 中声明内存部分时,我必须设置初始大小,并且可以设置可选的最大大小。

如果我将最大值设置为与初始值相同的值,它有什么优势吗?这个值对 WebAssembly 运行时有什么影响?

背景:我编写了一个Java 到 WebAssembly 编译器,并希望对我的数据使用即将到来的 GC 功能。我不需要增加记忆。我只会将它用于常量值。

4

1 回答 1

3

分配大内存(尤其是千兆字节时)可能会失败。未能分配初始内存是致命错误,而未能增加内存则不是。因此,从较小且安全的初始大小开始是个好主意。

WebAssembly 社区已经提供了非常好的文档:

我将在这里总结有关 WebAssembly 内存如何工作的信息。

为什么我们需要可选的最大尺寸

底层WebAssembly 内存是一个JS ArrayBuffer对象。ArrayBuffer 不是动态数组,这意味着它不能调整大小。但是,Wasm Memory 是一个特殊的 ArrayBuffer,可以通过Memory.grow()调用来调整大小,这与grow_memoryWasm 中的指令相对应。尽管如此,调整 ArrayBuffer 大小的实现成本很高 - 它与 相同realloc(),它分配一个具有新大小的新缓冲区,然后释放旧缓冲区。您可以通过分配大的初始内存来避免重新分配缓冲区的开销,但它会导致另一个问题,即操作可能会失败并且失败意味着 Wasm 引擎无法加载 Wasm 二进制文件。

可选的最大尺寸解决了这些问题。定义最大大小后,Wasm 内存会尝试预先分配缓冲区的最大大小。通过预先分配缓冲区,您可以稍后调整缓冲区的大小,而无需进行昂贵的realloc()操作。即使预分配操作失败也没关系 - 您可以稍后在需要时尝试重新分配。

WebAssembly 内存大小调整方案

  • grow_memory没有设置最大大小:Wasm 引擎尝试重新分配整个缓冲区,这非常昂贵并且增加了失败的可能性。
  • 分配一个大的初始内存:它可能会失败,它的失败是一个致命的错误。
  • grow_memory最大大小:引擎将立即使用预分配的缓冲区。即使它未能增长,也不是致命错误。
  • 设置初始大小 == 最大大小:您不会从其中任何一个中受益。它可能会遇到致命错误,并且您以后也无法调整它的大小。
于 2019-05-01T17:42:00.940 回答