gpt4 book ai didi

rust - Arc::new() 对于克隆向量很慢

转载 作者:行者123 更新时间:2023-12-03 09:26:38 24 4
gpt4 key购买 nike

执行此操作后:

use std::sync::Arc;
use std::time::Instant;
fn main() {
let cap = 100000000;
let b0 = vec![0; cap];
let now = Instant::now();
Arc::new(b0);
println!("T0: {:?}", now.elapsed());
let c0 = vec![0; cap];
let _ = c0.clone(); // <- this makes it slow
let now = Instant::now();
Arc::new(c0);
println!("T1: {:?}", now.elapsed());
}
结果是:
T0:5.971µs
T1:26.69574ms
如果我们之前克隆 c0,为什么第二个 Arc::new 很慢?
编辑:
我用以下方法测试了它:
  • Windows 10,rust 1.44.1 调试
  • Linux,Rust 1.47 每晚发布
  • Linux, rust 1.18
  • MacOS,Rust 1.44.0 每晚发布

  • T1 的时间随向量大小线性增加。

    最佳答案

    请注意,您不是在测量 Arc::new 所花费的时间,但您正在测量 Arc 被放下时所花费的时间(因为您没有将其分配给任何东西)。
    另请注意,根据您的系统,此行:

    let b0 = vec![0; cap];
    可能不分配任何物理内存:它只能分配虚拟空间,物理内存在第一次访问时被分配和归零。 cachegrind 证实了这一点,在克隆缓冲区之前几乎没有缓存未命中。
    克隆载体有两个副作用:
  • 它会导致物理内存被映射,这意味着在删除 Arc 时必须取消映射它。 ,
  • 它会破坏缓存(由于内存清零和复制),从而导致后续代码中的缓存未命中。

  • 使用以下代码将解除分配移出测量的时间,时间更快更接近:
    use std::sync::Arc;
    use std::time::Instant;

    fn main() {
    let cap = 1000000000;
    let b0 = vec![0; cap];
    let now = Instant::now();
    let a = Arc::new(b0);
    println!("T0: {:?}", now.elapsed());
    drop (a);
    let c0 = vec![0; cap];
    let _ = c0.clone(); // <- this makes it slow
    let now2 = Instant::now();
    let a = Arc::new(c0);
    println!("T1: {:?}", now2.elapsed());
    drop (a);
    }
    第二个 Arc::new仍然较慢,但可以通过 cachegrind 报告的 3 个额外的 L3 缓存未命中来解释差异。

    关于rust - Arc::new() 对于克隆向量很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63611943/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com