Rust 的 128 位整数 `i128` 如何在 64 位系统上工作? [英] How does Rust's 128-bit integer `i128` work on a 64-bit system?

查看:85
本文介绍了Rust 的 128 位整数 `i128` 如何在 64 位系统上工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust 有 128 位整数,用数据类型 i128 表示(对于无符号整数,u128):

Rust has 128-bit integers, these are denoted with the data type i128 (and u128 for unsigned ints):

let a: i128 = 170141183460469231731687303715884105727;

Rust 如何使这些 i128 值在 64 位系统上工作;例如它如何对这些进行算术运算?

How does Rust make these i128 values work on a 64-bit system; e.g. how does it do arithmetic on these?

由于,据我所知,该值无法放入 x86-64 CPU 的一个寄存器中,编译器是否以某种方式将 2 个寄存器用于一个 i128 值?还是他们使用某种大整数结构来表示它们?

Since, as far as I know, the value cannot fit in one register of a x86-64 CPU, does the compiler somehow use 2 registers for one i128 value? Or are they instead using some kind of big integer struct to represent them?

推荐答案

所有 Rust 的整数类型都编译为 LLVM 整数.LLVM 抽象机允许从 1 到 2^23 - 1 的任何位宽的整数.* LLVM 指令通常适用于任何大小的整数.

All Rust's integer types are compiled to LLVM integers. The LLVM abstract machine allows integers of any bit width from 1 to 2^23 - 1.* LLVM instructions typically work on integers of any size.

显然,8388607 位的架构并不多,所以当代码被编译为原生机器码时,LLVM 必须决定如何实现它.定义了add 等抽象指令的语义通过 LLVM 本身.通常,在本机代码中具有单指令等效项的抽象指令将被编译为该本机指令,而那些没有的将被仿真,可能使用多个本机指令.mcarton 的回答演示了 LLVM 如何编译本机指令和模拟指令.

Obviously, there aren't many 8388607-bit architectures out there, so when the code is compiled to native machine code, LLVM has to decide how to implement it. The semantics of an abstract instruction like add are defined by LLVM itself. Typically, abstract instructions that have a single-instruction equivalent in native code will be compiled to that native instruction, while those that don't will be emulated, possibly with multiple native instructions. mcarton's answer demonstrates how LLVM compiles both native and emulated instructions.

(这不仅适用于大于本机支持的整数,也适用于那些更小的整数.例如,现代架构可能不支持本机 8 位算术,因此 add两个 i8 上的 指令可以用更宽的指令模拟,多余的位被丢弃.)

(This doesn't only apply to integers that are larger than the native machine can support, but also to those that are smaller. For example, modern architectures might not support native 8-bit arithmetic, so an add instruction on two i8s may be emulated with a wider instruction, the extra bits discarded.)

编译器是否以某种方式将 2 个寄存器用于一个 i128 值?还是他们使用某种大整数结构来表示他们?

Does the compiler somehow use 2 registers for one i128 value? Or are they using some kind of big integer struct to represent them?

在 LLVM IR 级别,答案都不是:i128 适合单个寄存器,就像其他所有 单值类型.另一方面,一旦转换为机器代码,两者之间并没有真正的区别,因为结构可以像整数一样分解为寄存器.但是,在进行算术运算时,可以肯定的是,LLVM 只会将整个内容加载到两个寄存器中.

At the level of LLVM IR, the answer is neither: i128 fits in a single register, just like every other single-valued type. On the other hand, once translated to machine code, there isn't really a difference between the two, because structs may be decomposed into registers just like integers. When doing arithmetic, though, it's a pretty safe bet that LLVM will just load the whole thing into two registers.

* 然而,并非所有 LLVM 后端都是平等的.这个答案与 x86-64 相关.我知道后端对大于 128 和非 2 的幂的大小的支持是参差不齐的(这可以部分解释为什么 Rust 只公开 8 位、16 位、32 位、64 位和 128 位整数).根据 Reddit 上的 est31,rustc 位实现了 128 位整数面向不支持本机后端的软件.

* However, not all LLVM backends are created equal. This answer relates to x86-64. I understand that backend support for sizes larger than 128 and non-powers of two is spotty (which may partly explain why Rust only exposes 8-, 16-, 32-, 64-, and 128-bit integers). According to est31 on Reddit, rustc implements 128 bit integers in software when targeting a backend that doesn't support them natively.

这篇关于Rust 的 128 位整数 `i128` 如何在 64 位系统上工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆