Я хочу использовать новые инструкции по манипулированию битами, доступные в последних чипах Intel и AMD, в частности инструкцию PEXT
«Извлечение параллельных битов» (см. здесь и здесь). Как я могу получить доступ к этим инструкциям из Common Lisp? (в частности, SBCL).
В идеале я хотел бы получить доступ к этим инструкциям через библиотеку, которая определяет, предоставляет ли их ЦП, и, если нет, эмулирует их в программном обеспечении. Компиляторы для других языков предоставляют такие функции (например, GCC предоставляет функцию _pext_u32
; см. здесь).
Существует переменная (по крайней мере, в CMU Common Lisp, ответвлением которой является Steel Bank) под названием *features*
, которая перечисляет некоторую информацию о системе, в которой работает Lisp. Мой выглядит так:
(:GERDS-PCL :PCL-STRUCTURES :PORTABLE-COMMONLOOPS :PCL :CMU21 :CMU21B :PYTHON
:MODULAR-ARITH :MP :X86 :RELOCATABLE-STACKS :SSE2 :LINKAGE-TABLE
:RELATIVE-PACKAGE-NAMES :EXECUTABLE :MACH-O :DARWIN :BSD :UNIX :RANDOM-MT19937
:GENCGC :CMUCL :UNICODE :COMPLEX-FP-VOPS :HASH-NEW :ALIEN-CALLBACK
:DOUBLE-DOUBLE :HEAP-OVERFLOW-CHECK :STACK-CHECKING :COMMON-LISP :ANSI-CL
:IEEE-FLOATING-POINT :CMU)
Это может сказать вам то, что вам нужно знать. Если нет, попробуйте найти что-нибудь с (apropos 'feature)
, и он должен отобразить список символов с «особенностью» в них.
Я думаю, что для того, чтобы действительно добавить его поддержку, вам нужно изменить сам компилятор. Это может включать что-то вроде добавления новой VOP (см. Vop.lisp в исходниках sbcl), определение новой функции, которая компилируется с ней (возможно, в пакете sb-ext), и ее подключение. На самом деле я не могу сказать вам, как это сделать, мое понимание этого лишь поверхностное.
Другой способ, который может быть более переносимым, - создать библиотеку C, содержащую функции, которые используют новый примитив в сборке, а затем заключить ее в привязку CFFI.
Спасибо. Это интересные подходы, но проблема в том, что (а) изменение vop.lisp не очень переносимо, а CFFI добавляет накладные расходы (я хочу использовать инструкцию PEXT во внутреннем цикле, который выполняется миллиарды раз). Было бы идеально, если бы SBCL допускал встроенный ассемблерный код.
Думаю, я только что нашел здесь жизнеспособный подход: pvk.ca/Blog/2014/08/16/how-to-define-new-intrinsics-in-sbcl
SBCL действительно имеет эту переменную, но, похоже, она не показывает возможности процессора (например, в моем выводе нет SSE2). В любом случае знание функций ЦП полезно, но не дает ответа на вопрос (который касается того, как вызвать данную инструкцию ЦП из Common Lisp).