【NaN-Boxed】NaN Boxing of Narrower Values

unpriv-isa-asciidoc_20240411
21.“D” Extension,Version 2.2
21.2 NaN Boxing of Narrower Values

risc-v手册中规定了当架构支持多种浮点精度时,通过NaN-boxed来包装低位宽数据类型的数据,具体为:

  1. NaN Boxed是指用全位宽的NaN格式包装更窄位宽数据类型的数据。有效的NaN Boxed格式是除了n bit(n<FLEN)数据以外,高位为全1,也就是m位宽(n<m<FLEN)的数据作为-qNaN出现。
    举个例子
    在RV64架构中,同时支持F、D扩展,单精度浮点数【32’h$(value)】的摆放方式应该是:
{{32{1'b1}},32'h$(value)}
  1. 检查input格式,如果格式满足正确的NaN-boxed格式,将input的n位有效数据作为输入值,否则将输入值视为n位canonical NaN。
    手册规定标准的非数(canonical NaN)格式为:符号位为正,且尾数除MSB以外均为0。
single:0x7fc0_0000
double:0x7ff8_0000_0000_0000
### NaN Boxing 的概念及其与浮点数 NaN payload 的关联 #### 1. NaN Boxing 的定义 NaN Boxing 是一种技术,用于在单个机器字(通常是 64 位)中同时存储数据值和类型信息。这种技术的核心思想是利用浮点数中的 NaN 值的 payload 部分来存储额外的信息。由于 NaN 的尾数部分可以包含任意值,因此可以用来表示多种类型的动态数据[^2]。 例如,在 JavaScript 引擎中,NaN Boxing 被广泛用于实现动态类型系统。通过将整数、布尔值或其他类型的数据编码到 NaN 的 payload 中,可以在不增加内存占用的情况下支持多种数据类型[^3]。 #### 2. NaN Boxing 的实现机制 NaN Boxing 的实现依赖于 IEEE 754 标准中对 NaN 的定义。对于双精度浮点数(64 位),NaN 的按位结构如下: ``` S 11111111111 AX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX ``` - **S**:符号位。 - **11111111111**:指数部分全为 1。 - **A**:尾数部分的最高位,区分 qNaN 和 sNaN- **X**:payload 部分,用于存储额外信息。 通过设置特定的 payload 值,可以将不同类型的值编码到 NaN 中。例如: - 整数可以通过将整数值直接存储到 payload 中来表示。 - 布尔值可以通过分配固定的 payload 值(如 `0x0001` 表示 `true`,`0x0000` 表示 `false`)来实现。 以下是一个简单的 C++ 示例,展示如何使用 NaN Boxing 来存储整数: ```cpp #include <iostream> #include <bit> #include <cmath> // 定义一个函数,将整数编码为 NaN double encode_int(int value) { uint64_t nan = 0x7FF0000000000000; // 双精度浮点数的 NaN 模式 uint64_t payload = static_cast<uint64_t>(value); // 将整数作为 payload return std::bit_cast<double>(nan | (payload & 0x000FFFFFFFFFFFFF)); } // 定义一个函数,从 NaN 中解码整数 int decode_int(double value) { uint64_t bits = std::bit_cast<uint64_t>(value); return static_cast<int>(bits & 0x000FFFFFFFFFFFFF); } int main() { int original_value = 12345; double boxed_value = encode_int(original_value); int decoded_value = decode_int(boxed_value); std::cout << "Original: " << original_value << std::endl; std::cout << "Boxed: " << boxed_value << " (as double)" << std::endl; std::cout << "Decoded: " << decoded_value << std::endl; return 0; } ``` #### 3. NaN Boxing 的优势 - **内存效率**:通过复用浮点数的 NaN payload,避免了为每个值分配额外的内存空间。 - **性能优化**:由于所有值都存储在固定大小的机器字中,访问和操作这些值的速度更快。 - **兼容性**:许多现代处理器和编程语言已经支持 IEEE 754 标准,因此可以直接利用 NaN 的特性而无需额外的硬件支持[^4]。 #### 4. NaN Boxing 的局限性 - **可移植性问题**:不同平台可能对 NaN 的解释有所不同,导致跨平台兼容性问题。 - **调试困难**:由于 NaN 的 payload 被用作数据存储,调试时可能会难以区分正常 NaN 和被编码的值。 - **有限的 payload 空间**:对于单精度浮点数(32 位),可用的 payload 空间较小,限制了可存储的数据范围。 #### 5. NaN Boxing 与浮点数 NaN payload 的关系 NaN Boxing 技术直接利用了浮点数 NaN 的 payload 部分来存储额外信息。具体来说: - **payload 的灵活性**:IEEE 754 标准允许 NaN 的尾数部分包含任意值,这为存储不同类型的数据提供了可能性。 - **quiet NaN 的选择**:通常使用 quiet NaN(qNaN)而不是 signaling NaN(sNaN),因为 qNaN 不会触发异常,更适合用作数据容器[^5]。 通过这种方式,NaN Boxing 成为了实现高效动态类型系统的一种重要技术。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值