避免在Common Lisp中浮动到指针强制 [英] Avoiding float to pointer coercion in Common Lisp

查看:94
本文介绍了避免在Common Lisp中浮动到指针强制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use SBCL (64-bit v1.4.0) for numerical calculation. After enabling optimization, following compiler note appears:

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并得到相同的音符.

I've also tried ftype and got the same note.

另一方面,以下代码不显示注释:

On the other hand, following code doesn't show the note:

(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语言这样的寄存器返回双精度浮点数?还有什么方法可以避免在没有内联扩展的情况下浮动到指针强制?

I think double-float and fixnum are both 64 bits wide. Why can not SBCL return a double-float value via a register like C language? And are there any way to avoid float to pointer coercion without inline expansion?

推荐答案

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

The problem is that Lisp data is dynamically typed, and the return value of a function has to include the type information. The type tag in most implementations is stored in the low-order bits of a value.

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

This allows a special optimization for fixnums. Their type tag is all zeroes, and the value is the integer shifted left by the number of bits in the type tag. When you add these values, the result still has zeroes in the tag bits, so you can perform arithmetic on the values using normal CPU operations.

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

But this doesn't work for floating point values. After performing the CPU operations, it has to add the type tag to the value. This is what it means by "float to pointer coercion" (a more common word for it in many languages is "boxing").

声明返回类型并不能避免这种情况,因为调用者不一定具有对声明的访问权限-Lisp允许您在调用者所调用的函数之外的单独编译单元中对其进行编译.

Declaring the return type doesn't avoid this, because the callers don't necessarily have access to the declarations -- Lisp allows you to compile the callers in a separate compilation unit than the functions they call.

如果您声明函数INLINE,则无需执行此操作,因为调用方知道其返回的类型,并且可以直接向其返回硬件值,而无需添加标签.

If you declare the function INLINE, then this doesn't need to be done, because the callers know the type it's returning, and the hardware value can be returned directly to them without adding the tag.

在此古老的 comp中可以找到更详细的说明. lang.lisp线程.它指的是CMUCL,这是SBCL的来源(请注意,警告的措词是完全相同的.)

A more detailed explanation can be found in this ancient comp.lang.lisp thread. It's referring to CMUCL, which is what SBCL is derived from (notice that the wording of the warning is exactly the same).

这篇关于避免在Common Lisp中浮动到指针强制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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