Ho realizzato un piccolo modulo C per migliorare le prestazioni, ma GHC non esegue funzioni estranee inline e il costo delle chiamate elimina l'accelerazione. Ad esempio, test.h
:Come forzare GHC alle chiamate FFI in linea?
int inc (int x);
test.c
:
#include "test.h"
int inc(int x) {return x + 1;}
Test.hc
:
{-# LANGUAGE ForeignFunctionInterface #-}
module Test (inc) where
import Foreign
import Foreign.C
foreign import ccall unsafe "test.h inc" c_inc :: CInt -> CInt
inc = fromIntegral . c_inc . fromIntegral
{-# INLINE c_inC#-}
{-# INLINE inC#-}
Main.hs
:
import System.Environment
import Test
main = do {args <- getArgs; putStrLn . show . inc . read . head $ args }
Fare:
$ gcc -O2 -c test.c
$ ghc -O3 test.o Test.hs
$ ghc --make -O3 test.o Main
$ objdump -d Main > Main.as
Infine, nel Main.as
ho callq <inc>
istruzioni invece di desiderabili inc
's.
Si aspetta che ghc integri una funzione C nel suo codice generato? Questo potrebbe funzionare se si usa l'opzione -via-C, altrimenti è senza speranza (dal momento che richiederebbe ghc per leggere il codice C e generare codice per esso). – augustss
Non possibile in assenza di ottimizzazione del tempo di collegamento. Un approccio (hacky) da provare è compilare sia il bitcode Haskell che C-LLVM, combinare i file .bc con 'llvm-link', ottimizzare con' opt' e quindi emettere il codice eseguibile con 'llc'. –
@MikhailGlushenkov, potresti scrivere uno schizzo per creare una sequenza di comandi? Non sono riuscito a scoprire come ottenere i file '.bc' dal codice haskell. – leventov