rust - 我应该在 64 位机器上使用 i32 还是 i64?

标签 rust integer

ma​​in.rs

#![feature(core_intrinsics)]
fn print_type_of<T>(_: &T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}

fn main() {
    let x = 93;
    let y = 93.1;

    print_type_of(&x);
    print_type_of(&y);
}

如果我用“rustc +nightly ./main.rs”编译,我得到这个输出:

$ ./main

i32
f64

我运行的是 x86_64 Linux 机器。默认情况下,浮点变量是 double 的,这很好。 为什么整数只有 4 个字节?我应该使用哪个?如果我不需要 i64,我应该使用 i32 吗? i32 的性能更好吗?

最佳答案

Are i32 better for performance?

这实际上是一件微妙的事情。如果我们查找一些 recent instruction-level benchmarks例如 SkylakeX在大多数情况下 64 位和 32 位指令之间非常明显没有区别。除法是一个异常(exception),64 位除法比 32 位除法慢,即使是对相同的值进行除法也是如此(除法是为数不多的取决于其输入值的可变时间指令之一)。

对数据使用 i64 也会降低自动矢量化的效率 - 这也是小于 32 位的数据具有超出数据大小优化用途的罕见地方之一。当然,数据大小对于 i32 与 i64 的问题也很重要,使用 i64 的大数组很容易变慢,因为它更大,因此需要更多的缓存空间和(如果适用)更多的带宽。因此,如果问题是 [i32][i64],那么它很重要。

更微妙的是,使用 64 位操作意味着代码将平均包含更多的 REX 前缀,从而使代码的密度略微降低,这意味着更少的代码可以一次放入 L1 代码缓存中。虽然这是一个很小的影响。在代码中只包含一些 64 位变量不是问题。

尽管如此,绝对不要过度使用 i32,尤其是在您真正应该使用的地方。例如,不要这样做:

// don't do this
for i in 0i32 .. data.len() as i32 { 
  sum += data[i as usize]; 
}

这会导致性能大幅下降。现在循环中不仅有一个毫无意义的符号扩展,它还破坏了边界检查消除和自动矢量化。但当然,一开始就没有理由编写那样的代码,这不自然,而且比正确执行更难。

关于rust - 我应该在 64 位机器上使用 i32 还是 i64?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51685509/

相关文章:

multithreading - 使用非重叠向量 block ,并合并结果

c++ - 如何在 Rust 中将绑定(bind)传递给 sqlite3?

java - 静态错误 : This class does not have a static void main method accepting String[]

c# - int 是枚举的支持类型

typescript - 如何在 typescript 文件中导入由 wasm-pack 生成的 wasm 文件?

rust - 使用枚举对结构进行分组

cuda - 您如何将用 C 编写的自定义 CUDA 内核链接到 Rust 项目?

java - 尝试将 List<String> 转换为 List<Integer> 时出错

C - 具有 n 个 unsigned int 属性的哈希结构

c# - 如何将数字转换为价格范围