为什么 64 位乘法的性能与 32 位乘法相当?

Why is performance of 64bit multiplication comparable to 32bit multiplication?

我正在测量两个 64 位数字相乘与两个 32 位数字相乘时的 Rust 性能。回想一下,64 位乘法的结果是 128 位数字,32 位乘法的结果是 64 位数字。我预计 64 位乘法至少比另一个慢 2 倍。主要是因为没有本机 128 位支持,要将两个 64 位数字相乘,您将它们分成 32 位高位和低位。然而,当我 运行 测试时,结果两者表现相似。

这是我用过的脚本:

fn main() {
    test_64_mul();
    test_32_mul();
}

fn test_64_mul() {
    let test_num: u64 = 12345678653435363454;
    use std::time::Instant;
    let mut now = Instant::now();
    let mut elapsed = now.elapsed();
    for _ in 1..2000 {
        now = Instant::now();
        let _prod = test_num as u128 * test_num as u128;
        elapsed = elapsed + now.elapsed();
    }
    println!("Elapsed For 64: {:.2?}", elapsed);
}

fn test_32_mul() {
    let test_num: u32 = 1234565755;
    use std::time::Instant;
    let mut now = Instant::now();
    let mut elapsed = now.elapsed();
    for _ in 1..2000 {
        now = Instant::now();
        let _prod = test_num as u64 * test_num as u64;
        elapsed = elapsed + now.elapsed();
    }
    println!("Elapsed For 32: {:.2?}", elapsed);
}

运行这段代码后的输出是

64 秒耗时:25.58µs

已用 32:26.08µs

我正在使用配备 M1 芯片的 MacBook Pro 和 Rust 版本 1.60.0

因为编译器注意到你没有使用结果,所以完全消除了乘法。

https://rust.godbolt.org/z/5sjze7Mbv 查看差异。

你应该使用 std::hint::black_box(), or much better, a benchmarking framework like criterion.

此外,每次创建新 Instant 的开销可能比乘法本身高得多。就像我说的,使用基准测试框架。

如@StephenC 所述,您的时钟分辨率也不太可能小到足以测量一次乘法。