как это влияет на производительность при совершении звонков на него
Предполагая, что вы запускаете среду выполнения Haskell только один раз ( как этот ) на моей машине,выполнение вызова функции из C в Haskell, передача Int вперед и назад через границу, занимает около 80 000 циклов ( 31 000 нс на моем Core 2) - определяется экспериментально через rdstc register
Могу ли я сохранить эти 20 КБ данных в качестве глобальной неизменяемой ссылки где-нибудь, к которой обращается код Haskell
Да, это, конечно, возможно.Если данные действительно неизменны, то вы получите тот же результат, если вы:
- продвигаете данные вперед и назад через границу языка путем маршаллинга;
- передаете ссылку на данныетуда-сюда;
- или кэшируйте его в
IORef
на стороне Haskell.
Какая стратегия лучше?Это зависит от типа данных.Наиболее идиоматичным способом было бы передавать ссылку на данные C взад-вперед, обрабатывая ее как ByteString
или Vector
на стороне Haskell.
Я бы хотел распараллелить это
Я бы настоятельно рекомендовал бы тогда инвертировать элемент управления и выполнить распараллеливание из среды выполнения Haskell - это будет намного более устойчивым, поскольку этот путь был тщательно протестирован.
Что касается безопасности потоков, очевидно, безопасно выполнять параллельные вызовы функций foreign exported
, работающих в одной и той же среде выполнения, хотя и вполне уверен, что никто не пытался сделать это для получения параллелизма.Вызовы получают возможность, которая по сути является блокировкой, поэтому множественные вызовы могут блокироваться, уменьшая ваши шансы на параллелизм.В случае многоядерности (например, -N4
или около того) ваши результаты могут отличаться (доступно несколько возможностей), однако это почти наверняка плохой способ повысить производительность.
Опять же, много параллельных вызовов функцийиз Haskell через forkIO
- это более хорошо документированный, лучше протестированный путь, с меньшими накладными расходами, чем работа на стороне C, и, возможно, с меньшим количеством кода в конце.
Просто вызовите функцию Haskell,это, в свою очередь, приведет к параллелизму через множество потоков на Haskell.Легко!