当Rust WASM与+ Atomics flag webAssembly编译时,只有1/4的最大内存可用

发布于 2025-01-31 02:58:55 字数 1952 浏览 3 评论 0原文

因此,用 +原子标志的WASM/Rust用完了记忆,并想检查实际上可用的内存。这是我的粗略的最小工作示例,它在恐慌之前记录了向量的内存:

index.js

import init from './pkg/test1.js';
import * as wasm_test1 from './pkg/test1.js';
async function run() {
  await init();
  let newDiv = document.createElement("div");
  let btn = document.createElement("button");
  btn.innerHTML = "Max out the memory now and panic!";
  document.body.appendChild(btn);

  btn.onclick = function () {
    wasm_test1.fill_memory();
  };
}
run();

lib.rs

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
pub fn fill_memory() {
    let mut v  = Vec::new();
    for i in 1..1000000000 {
        v.push(0);
        if (i % 10000) == 0 {
            let v_size = (std::mem::size_of_val(&*v)/1024/1024).to_string();
            log(&format!("{}", v_size+"Mb"));
        }
    }
    std::mem::forget(v);
}

cargo.toml

..
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.80"
wasm-bindgen-futures = "0.4.30"

.cargo/config

[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]

[unstable]
build-std = ["panic_abort", "std"]

这是我观察到的:

无标志+原子
最大内存可用1024MB256MB
浏览器峰值内存消耗(在任务管理器中)2550MB 750MB750MB
浏览器闲置内存消耗(在任务管理器中)225MB225MB

注意, +原子也需要删除其他标志,但是我需要删除其他标志此标志(并保留其他标志)行为与没有标志相同。在恐慌之前,256MB和1024MB之前的两种情况下,可用的内存非常精确。那么,当我为更高内存设置内存标志时会发生什么? 的,完全是最大内存的1/4

+Atomics标志可用的内存是一致

  • 。我要改善这一点?
  • 为什么总记忆限制为1 GB?
  • 当向量仅1GB时,浏览器为什么使用2.5GB内存(也许有一点开销)?

So, I've been running out of memory with wasm/rust with +atomic flag and wanted to check how much memory is practically available. Here is my crude minimal working example that logs the memory of a vector before it panics:

index.js

import init from './pkg/test1.js';
import * as wasm_test1 from './pkg/test1.js';
async function run() {
  await init();
  let newDiv = document.createElement("div");
  let btn = document.createElement("button");
  btn.innerHTML = "Max out the memory now and panic!";
  document.body.appendChild(btn);

  btn.onclick = function () {
    wasm_test1.fill_memory();
  };
}
run();

lib.rs

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
pub fn fill_memory() {
    let mut v  = Vec::new();
    for i in 1..1000000000 {
        v.push(0);
        if (i % 10000) == 0 {
            let v_size = (std::mem::size_of_val(&*v)/1024/1024).to_string();
            log(&format!("{}", v_size+"Mb"));
        }
    }
    std::mem::forget(v);
}

Cargo.toml

..
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.80"
wasm-bindgen-futures = "0.4.30"

.cargo/config

[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]

[unstable]
build-std = ["panic_abort", "std"]

Here is what I observe:

No flags+atomics
max memory available1024Mb256Mb
Browser peak memory consumption (in task manager)2550Mb750Mb
Browser idle memory consumption (in task manager)225Mb225Mb

Note that +atomics also requires a couple of other flags to be present, but if I remove this flag (and keep the others) the behavior is identical to no flags. The available memory is very precise in the two cases before panic, 256Mb and 1024Mb. So what happens when I set memory flag for higher memory? The memory available with +atomics flag is consistenly, exactly, 1/4th of the total max memory.

I have a few questions:

  • Why is the memory 1/4th when using +atomic flag, and what can I do to improve this?
  • Why is total memory capped at 1 Gb?
  • Why does the browser use 2.5Gb memory when vector is only 1Gb (and maybe with a little overhead)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北笙凉宸 2025-02-07 02:58:55

对于这里遇到此问题的任何人,这里有几个问题。最终,我能够要求所有记忆。

  1. 看来,生锈工作中动态分配的向量的方式是,当元素被推开并且用完当前空间时,分配会加倍。因此,尽管还有更多可用的记忆,但它使近一半的内存感到恐慌。 :: with_capacity在这里帮助我帮助了
  2. Rust编译器中的某种默认设置,其中 +Atomics标志将内存限制为1GB。您可以通过添加一个Rust Frag在货物配置文件中更改此默认值,以下类似于下面的4G(Chrome允许WASM的最大值):
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C",
 "link-arg=--max-memory=4294967296"]

For anyone running into this issue here, there were a couple of issues at play here. I was, eventually, able to claim all the memory.

  1. It appears that dynamically allocated vectors in rust work in a way that when elements are pushed and you run out of current space, the allocation is doubled. As such, it panicked closer to half the memory though more was available. ::with_capacity helped me out here
  2. There's some sort of default set in rust compiler with the +atomics flag that caps memory to 1Gb. You can change this default in the cargo config file by adding a rust flag, something like the below to get 4G (the max that chrome allows for WASM):
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C",
 "link-arg=--max-memory=4294967296"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文