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

时间:2018-08-04 12:21:32

标签: rust integer

main.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计算机。浮点变量默认情况下是双精度的,这很好。 为什么整数只有4个字节?我应该使用哪个?如果不需要i64,应该使用i32吗? i32的性能更好吗?

3 个答案:

答案 0 :(得分:4)

The Rust Programming Language说:

  

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

然后(in the next section):

  

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


但是,这是相当简化的。您应该使用哪种整数类型在很大程度上取决于您的程序。最初编写程序时,请不要考虑速度,除非您已经知道速度将是一个问题。在绝大多数代码中,速度并不重要:即使在性能至关重要的应用程序中,大多数代码还是冷代码。相反,正确性总是很重要

还要注意,只有 unconstrained 数值变量默认为i32 / f64。在需要特定数字类型的上下文中使用变量后,编译器将立即使用该类型。

答案 1 :(得分:4)

  

i32的性能更好吗?

这实际上是一种微妙的事情。如果我们以recent instruction-level benchmarks为例查看SkylakeX,那么在大多数情况下, 显然没有64位和32位指令之间的差异。例外是除法,即使对相同的值进行除法,64位除法也比32位除法慢(除法是为数不多的取决于其输入值的可变时间指令之一)。

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

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

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

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

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

答案 2 :(得分:0)

首先,您应该根据自己的需求/要求设计应用程序。也就是说,如果您需要“大”整数,请使用大类型。如果不需要它们,则应使用小型字体。

如果您遇到任何性能问题(并且仅此),则应将类型调整为您可能不需要的类型。