我应该在64位计算机上使用i32还是i64?

Gio*_*ano 1 integer rust

#![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);
}
Run Code Online (Sandbox Code Playgroud)

如果我使用“ rustc + nightly ./main.rs”进行编译,则会得到以下输出:

$ ./main

i32
f64
Run Code Online (Sandbox Code Playgroud)

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

Luk*_*odt 8

Rust 编程语言说:

[...] 整数类型默认为i32:这种类型通常是最快的,即使在 64 位系统上也是如此。

和(在下一节中):

默认类型是f64因为在现代 CPU 上它的速度大致相同,f32但精度更高。


然而,这是相当简单的。您应该使用哪种整数类型在很大程度上取决于您的程序。最初编写程序时不要考虑速度,除非您已经知道速度会成为问题。在绝大多数代码中,速度并不重要:即使在性能关键的应用程序中,大多数代码也是冷代码。相比之下,正确性总是很重要的

另请注意,只有不受约束的数字变量默认为i32/ f64。只要您在需要特定数字类型的上下文中使用该变量,编译器就会使用该类型。


har*_*old 5

i32的性能更好吗?

这实际上是一种微妙的事情。如果我们查看一些最新的指令级基准(例如SkylakeX),则在大多数情况下,显然在64位和32位指令之间没有明显的区别。例外是除法,即使对相同的值进行除法,64位除法也比32位除法慢(除法是少数几个依赖于其输入值的可变时间指令之一)。

对数据使用i64也会使自动矢量化的效率降低-这也是小于32位的数据除了数据大小优化之外还具有其他用途的罕见地方之一。当然,数据大小对于i32 vs i64问题也很重要,使用较大的i64阵列可能会很慢,因为它更大,因此会占用更多的缓存空间(如果适用)和更多的带宽。因此,如果问题是[i32]vs [i64],那么这很重要。

更微妙的事实是,使用64位操作意味着代码平均将包含更多的REX前缀,从而使代码的密度略低,这意味着较少的代码将立即放入L1代码缓存中。但是,这是一个很小的效果。在代码中只包含一些64位变量不是问题。

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

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

这会导致较大的性能下降。现在,循环中不仅没有无意义的符号扩展,而且还克服了边界检查消除和自动矢量化的问题。但是当然,首先没有理由编写这样的代码,这比正确地编写代码不自然且更难。