Похоже, вы не будете возражать против затрат на вызов функции OCaml, если вызываемая вами функция может быть написана на ассемблере.Я только что провел некоторые эксперименты, и вы можете сделать это способом, описанным выше.
Вот что я сделал.Чтобы получить работающий шаблон на ассемблере, я определил простую функцию в OCaml и скомпилировал с флагом -S.
$ cat sep.ml
let addto x = x + 1
$ /usr/local/ocaml312/bin/ocamlopt -inline 0 -c -S sep.ml
Примечание: вам нужно указать -inline 0
, чтобы убедиться, чтоocamlopt берет код из вашего сгенерированного файла .o, а не из встроенного определения в файле .cmx.
Теперь у вас есть файл с именем sep.s.Функция addto
выглядит следующим образом (на самом деле удивительно хороший код):
_camlSep__addto_1030:
.L100:
addq $2, %rax
ret
Просто для теста я изменил 2 (который представляет 1 в OCaml) на 4 (который представляет 2 в OCaml),Итак, теперь у вас есть:
_camlSep__addto_1030:
.L100:
addq $4, %rax
ret
Теперь соберите этот файл, создавая отклоняющуюся версию sep.o.
$ as -o sep.o sep.s
По сути, вы обманули ocamlopt для обработки кода в sep.о как будто это было закодировано в OCaml.Но вы можете написать код самостоятельно в сборке (если вы будете осторожны, чтобы не нарушить какие-либо архитектурные предположения).
Вы можете связать его с основной программой и запустить:
$ cat main.ml
let main () =
Printf.printf "%d\n" (Sep.addto 19)
let () = main ()
$ /usr/local/ocaml312/bin/ocamlopt -o main sep.cmx main.ml
$ main
21
Как видите, он запускает измененный код сборки.
Вы можете выполнить эту процедуру для создания любых функций, вызываемых OCaml, в коде сборки.Пока вы не возражаете против накладных расходов на вызов функции OCaml, этот подход может делать то, что вы хотите.
Я не знаю, как эта хитрость повлияет на обработку отладки и сборку мусора, поэтому яЯ бы не стал делать это с функцией, которая выполняет какое-либо распределение.
Эти тесты были запущены на Mac OS X 10.6.8 с использованием OCaml 3.12.0 (стандартная 64-битная сборка).Когда я запускаю «как», я запускаю стандартный ассемблер OS X из Xcode 4.0.2, который по умолчанию использует архитектуру x86_64.