optimization - 避免 float 到 Common Lisp 中的指针强制转换

标签 optimization double common-lisp

我使用SBCL(64位v1.4.0)进行数值计算。
启用优化后,会出现以下编译器注释:

note: doing float to pointer coercion (cost 13) to "<return value>"

我使用的代码如下:
(defun add (a b)
  (declare (optimize (speed 3) (safety 0)))
  (declare (double-float a b))
  (the double-float (+ a b)))

我也试过 ftype并得到相同的笔记。

另一方面,以下代码不显示注释:
(defun add-fixnum (a b)
  (declare (optimize (speed 3) (safety 0)))
  (declare (fixnum a b))
  (the fixnum (+ a b)))

我认为 double-float 和 fixnum 都是 64 位宽。
为什么SBCL不能像C语言一样通过寄存器返回一个双浮点值?有没有办法避免 float 到指针强制而没有内联扩展?

最佳答案

问题是 Lisp 数据是动态类型的,函数的返回值必须包含类型信息。大多数实现中的类型标签存储在值的低位。

这允许对 fixnum 进行特殊优化。它们的类型标记全为零,值是左移类型标记中位数的整数。当您添加这些值时,结果的标记位中仍然包含零,因此您可以使用正常的 CPU 操作对这些值执行算术运算。

但这不适用于浮点值。在执行 CPU 操作后,它必须将类型标记添加到值中。这就是“ float 到指针强制”的含义(在许多语言中更常见的词是“装箱”)。

声明返回类型并不能避免这种情况,因为调用者不一定有权访问声明——Lisp 允许您在与调用函数不同的编译单元中编译调用者。

如果你声明函数 INLINE ,那么这个就不需要了,因为调用者知道它返回的类型,硬件值可以直接返回给他们,不用加标签。

更详细的解释可以在这个古老的comp.lang.lisp thread中找到。 .它指的是 CMUCL,它是 SBCL 的派生词(注意警告的措辞完全相同)。

关于optimization - 避免 float 到 Common Lisp 中的指针强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47450450/

相关文章:

sockets - usockets : How do I specify the external format when I open a socket

javascript - 优化html5 Canvas 游戏

Java:需要帮助优化部分代码

parsing - Haskell 无法读取这个 double : ".3". 这是一个错误吗?

Java DecimalFormat 在格式化 double 时失去精度

按普通 lisp 中的两个属性排序

MySql - 进一步查询优化SELECT WHERE IN

Python 不使用 xlsxwriter 创建 Excel 文件

C:函数参数输入看似随机变化

optimization - 如何优化我的递归 Lisp 函数