Каково влияние объявлений ftype на встроенные функции в SBCL?

Я основываюсь на каком-то старом коде Common Lisp, написанном другими, который включает такие строки, как следующие, в начале нескольких функций:

(declare (ftype (function (&rest float) float) + - * min max))

Насколько я понимаю, цель этого состоит в том, чтобы сообщить компилятору, что пять функций, перечисленных в конце формы, будут передаваться только с плавающей запятой. Компилятор может использовать эту информацию для создания более эффективного кода.

Некоторые Лиспы не жалуются на это объявление (ABCL, CCL, ECL, LispWorks, CLISP), но SBCL не примет это объявление в конфигурации по умолчанию. SBCL можно заставить принять его, поместив

(unlock-package 'common-lisp)

в файле инициализации .sbclrc. Это то, чем я занимаюсь последний год или около того. Я предполагаю, что это необходимо, потому что в этом пакете есть +, - и т. д., и код изменяет объявления этих функций.

Мой вопрос: может ли объявление типа функции встроенных функций, таких как + и min, оказать благотворное влияние на скомпилированный код в SBCL? (Если может, то почему SBCL жалуется на эти объявления по умолчанию?) Не лучше ли удалить такие объявления ftype, а затем избавиться от строки unlock-package в .sbclrc?

Спасибо.


person Mars    schedule 01.01.2013    source источник


Ответы (1)


Насколько я понимаю, цель этого состоит в том, чтобы сообщить компилятору, что пять функций, перечисленных в конце формы, будут передаваться только с плавающей запятой. Компилятор может использовать эту информацию для создания более эффективного кода.

Кроме того, они будут возвращать только поплавки. При определенных настройках оптимизации компилятор Common Lisp не генерирует проверки во время выполнения и может генерировать код только для вычислений с плавающей запятой. Также SBCL может отображать предупреждения во время компиляции в некоторых случаях, когда обнаруживает, что код нарушает объявления типов.

Это также источник ошибок, поскольку отныне (в рамках объявления) базовые функции, такие как + и -, объявлены не работающими с другими типами чисел (целыми, комплексными,...).

Итак, какова цель этих деклараций? Поскольку это переносимый код (и большинство реализаций не реализуют проверку типов во время компиляции), он может использоваться только в целях оптимизации. Некоторые из них могут не понадобиться в SBCL, поскольку он использует вывод типов.

Почему SBCL по умолчанию не позволяет изменять встроенный функционал? Это так, чтобы не выстрелить себе в ногу: вы меняете базовый язык. Теперь основные числовые операции могут привести к ошибкам.

Способы борьбы с этим:

  • используйте только локальные объявления, не изменяйте язык глобально. Вы указываете, что они объявлены только локально - это хорошо.

  • вместо этого объявить значения переменных

  • написать специальные функции для случая с плавающей запятой и объявить их встроенными.

  • только разблокируйте пакет CL во время компиляции этих нескольких функций. держать его заблокированным позже.

Мой вопрос: может ли объявление типа функции встроенных функций, таких как + и min, оказать благотворное влияние на скомпилированный код в SBCL?

Вы можете проверить это, просмотрев дизассемблированный код, а также профилируя. Убедитесь, что вы скомпилировали функцию с правильными параметрами оптимизации. В Common Lisp функция DISASSEMBLE должна показывать вам машинный код в удобочитаемом виде. Компилятор SBCL также должен сообщить вам, если он не может оптимизировать скомпилированный код.

person Rainer Joswig    schedule 01.01.2013
comment
Спасибо Райнер. Полезная информация и полезные указатели - достаточно, чтобы я начал изучать вещи, о которых я был в неведении. - person Mars; 03.01.2013