为什么 V8 使用指针标记而不是 NaN 装箱?
Why does V8 uses pointer tagging and not NaN boxing?
我现在正在学习 V8 的内部结构。我了解到 V8 使用 pointer tagging 进行值存储,但想知道为什么它不使用 NaN 装箱。
AFAIK,NaN 拳击更好,因为它还可以存储双打而不仅仅是 SMI。我已阅读 this,并理解(如果那是真的)为什么不在 32 位平台上使用 NaN 装箱。但是在 64 位平台上我不明白为什么。
我怀疑原因与SMI有关。也许它们不能使用 NaN 装箱存储?我认为他们可以。我们有 52 个多余的位(我们甚至可以使用超过 32 个位)。也许这将需要额外的屏蔽操作,这会使整数数学运算变慢?但是我们已经需要进行位移了!
我不知道为什么。感谢任何愿意回答的人。
(此处为 V8 开发人员。)NaN 装箱和指针标记是具有不同权衡的设计选择,两者严格来说并不比另一个更好。 V8 使用指针标记的决定早在我加入该项目之前就已经做出了,所以我只能推测当时可能是什么具体原因。
指针标记的优点是:
- 显着减少内存消耗(当然在 32 位平台上;在 64 位平台上也有“pointer compression”)
- 稍微更高效(小)整数运算,因为大多数 CPU 的整数运算比它们的双精度运算更快。一旦优化编译器进入画面,这可能根本不重要。
- 指针操作稍微更有效,因为您可以在访问对象字段时简单地添加一个调整后的偏移量(这与根本不玩任何指针技巧具有相同的性能),而不是必须屏蔽掉不相关的部分南。一旦优化编译器进入画面,这可能根本不重要。
正如您所指出的,NaN 标记的主要好处是它支持完整的双范围,这在某些情况下非常好。您可以基于任一技术构建 well-performing 引擎。
我现在正在学习 V8 的内部结构。我了解到 V8 使用 pointer tagging 进行值存储,但想知道为什么它不使用 NaN 装箱。
AFAIK,NaN 拳击更好,因为它还可以存储双打而不仅仅是 SMI。我已阅读 this,并理解(如果那是真的)为什么不在 32 位平台上使用 NaN 装箱。但是在 64 位平台上我不明白为什么。
我怀疑原因与SMI有关。也许它们不能使用 NaN 装箱存储?我认为他们可以。我们有 52 个多余的位(我们甚至可以使用超过 32 个位)。也许这将需要额外的屏蔽操作,这会使整数数学运算变慢?但是我们已经需要进行位移了!
我不知道为什么。感谢任何愿意回答的人。
(此处为 V8 开发人员。)NaN 装箱和指针标记是具有不同权衡的设计选择,两者严格来说并不比另一个更好。 V8 使用指针标记的决定早在我加入该项目之前就已经做出了,所以我只能推测当时可能是什么具体原因。
指针标记的优点是:
- 显着减少内存消耗(当然在 32 位平台上;在 64 位平台上也有“pointer compression”)
- 稍微更高效(小)整数运算,因为大多数 CPU 的整数运算比它们的双精度运算更快。一旦优化编译器进入画面,这可能根本不重要。
- 指针操作稍微更有效,因为您可以在访问对象字段时简单地添加一个调整后的偏移量(这与根本不玩任何指针技巧具有相同的性能),而不是必须屏蔽掉不相关的部分南。一旦优化编译器进入画面,这可能根本不重要。
正如您所指出的,NaN 标记的主要好处是它支持完整的双范围,这在某些情况下非常好。您可以基于任一技术构建 well-performing 引擎。