为什么 V8 使用指针标记而不是 NaN 装箱?

2024-03-17

我现在正在学习V8内部原理。我了解到V8使用指针标记 https://en.wikipedia.org/wiki/Tagged_pointer用于值存储,但想知道为什么不使用 NaN 装箱。

AFAIK,NaN 拳击更好,因为它还可以存储双打,而不仅仅是 SMI。我读了this https://news.ycombinator.com/item?id=16985390,并理解(如果这是真的)为什么不在 32 位平台上使用 NaN 装箱。但在 64 位平台上我不明白为什么。

我怀疑原因与 SMI 有关。也许它们不能使用 NaN 拳击来存储?我认为他们可以。我们为它们准备了 52 个多余的位(我们甚至可以使用超过 32 位)。也许这需要额外的掩码操作,从而使整数数学变慢?但我们已经需要进行按位移位了!

我不知道为什么。感谢任何愿意回答的人。


(这里是 V8 开发人员。)NaN 装箱和指针标记是具有不同权衡的设计选择,严格来说,两者都不比另一个更好。 V8 使用指针标记的决定早在我加入该项目之前就已经做出了,所以我只能推测当时的具体原因是什么。

指针标记的优点是:

  • 显着减少内存消耗(当然在 32 位平台上;使用“指针压缩 https://v8.dev/blog/pointer-compression" 在 64 位平台上也是如此)
  • (小)整数运算效率稍高,因为大多数 CPU 的整数运算比双精度运算更快。一旦优化编译器介入,这可能就不再重要了。
  • 指针操作的效率稍微高一些,因为您可以在访问对象字段时简单地添加调整后的偏移量(其性能与根本不玩任何指针技巧相同),而不是必须屏蔽 NaN 的不相关部分。一旦优化编译器介入,这可能就不再重要了。

正如您所指出的,NaN 标记的主要好处是它支持完整的双范围,这在某些情况下非常好。您可以基于任一技术构建性能良好的引擎。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 V8 使用指针标记而不是 NaN 装箱? 的相关文章

  • 如何优化这个查询(涉及4毫米表)

    我正在使用如下所示的遗留数据库架构 product table表有字段 uid 整数 主键 name varchar 50 category表有字段 uid 整数 主键 name varchar 50 好吧 现在product table与
  • EASTL 与 STL 相比,std::vector::operator[] 怎么会有这么大的性能差异

    根据http www open std org jtc1 sc22 wg21 docs papers 2007 n2271 html http www open std org jtc1 sc22 wg21 docs papers 2007
  • 为什么这个声明的解引用类型双关指针警告是编译器特定的?

    我读了various https stackoverflow com questions 8824622 fix for dereferencing type punned pointer will break strict aliasin
  • 最大化数组中成对距离的总和

    想象一个清单 e1 e2 en 和一个函数f e1 e2 gt number返回常数时间内任意两个元素之间的距离 f e e 0 e1 e2 gt f e1 e2 gt 0 f e1 e2 lt f e1 e3 f e3 e2 目标是排列列
  • 推迟未使用的 CSS

    我有一个关键的 CSS 流程 可以防止页面首屏内容出现无样式内容闪现 FOUC 我陷入了 推迟未使用的 CSS 这一点 Google PageSpeed 见解 灯塔 和 或 Chrome 的性能审核强调了这一点 我已经阅读了其他文章 但它们
  • 通过派生指针调用基类函数

    Objective C 如何使用派生指针调用基类函数 其中 foo 在派生类中被重写 本质上相当于这个 C 代码 base b ptr 0 derived d ptr new derived d gt base foo 我认为这应该相当简单
  • malloc和gcc优化2

    while count lt 30000000 malloc 24 count 上面的代码在我用 gcc O0 编译的计算机上运行大约需要 170 毫秒 但是 使用 Ox 其中 x gt 0 进行编译时 优化器会巧妙地发现所请求的内存永远不
  • iPhone - dequeueReusableCellWithIdentifier 用法

    我正在开发一个 iPhone 应用程序 它有一个相当大的 UITableView 其中的数据来自网络 所以我正在尝试优化它的创建和使用 我发现dequeueReusableCellWithIdentifier非常有用 但是在看到很多使用它的
  • MSVC 可能/不太可能等效

    GCC 编译器支持 builtin expect 语句 用于定义可能和不可能的宏 eg define likely expr builtin expect expr 1 define unlikely expr builtin expect
  • 快速平方根优化?

    如果你检查这个非常好的页面 http www codeproject com Articles 69941 Best Square Root Method Algorithm Function Precisi http www codepr
  • 通过引用传递参数到指针问题

    每次我尝试编译代码时都会收到错误 cannot convert parameter 1 from int to int 测试代码如下所示 void set int val val 10 int main int myVal int pMyV
  • 完全禁用 NVCC 优化

    我正在尝试测量 GPU 上的峰值单精度触发器 为此我正在修改 PTX 文件以在寄存器上执行连续的 MAD 指令 不幸的是 编译器正在删除所有代码 因为它实际上没有做任何有用的事情 因为我没有执行任何数据的加载 存储 是否有编译器标志或编译指
  • Golang 基础知识 struct 和 new() 关键字

    我正在学习 golang 当我阅读描述结构的章节时 我遇到了初始化结构的不同方法 p1 passport var p2 passport p3 passport Photo make byte 0 0 Name Scott Surname
  • 计算 [1..N] 中前导 1 下面有 K 个零位的整数? (没有 HW POPCNT 的连续范围的 popcount)

    I have following task Count how many numbers between 1 and N will have exactly K zero non leading bits e g 710 1112 will
  • char* argv[] 在 c/c++ 中如何工作? [复制]

    这个问题在这里已经有答案了 我知道它用于使用命令行中的参数 但我没有得到声明 字符 argv 它是否意味着指向 char 数组的指针 如果是的话为什么没有大小 如果不是动态数组 就不需要有大小吗 我做了一些研究 发现有人说它会衰减为 cha
  • 如何从尖点库矩阵格式获取原始指针

    我需要从尖点库矩阵格式获取原始指针 例如 cusp coo matrix
  • Fortran 指针数组

    同样 Fortran 中的指针数组 好吧 我有一个派生类型 type t context pointer type t context pointer p ctx end type t context pointer 当我在主程序中执行以下
  • 删除指向对象的 C++ 指针

    我认为删除命令会释放我分配的内存 有人可以解释为什么删除后我似乎仍然有内存在使用吗 class Test public int time int main Test e e new Test e gt time 1 cout lt lt e
  • 相当于 min() 的 rowMeans()

    我在 R 邮件列表上多次看到这个问题 但仍然找不到满意的答案 假设我有一个矩阵m m lt matrix rnorm 10000000 ncol 10 我可以通过以下方式获得每行的平均值 system time rowMeans m use
  • NodeJS:调用 global.gc() 不会将内存减少到最低限度?

    为了调查内存泄漏 我设置了一条触发的路线global gc 在每个POST gc app post gc function req res global gc 但是 我注意到 如果我发送垃圾邮件此请求 每次都会越来越多地减少内存使用量 不应

随机推荐