Ich machte kleine C-Modul, um die Leistung zu verbessern, aber GHC nicht inline Fremdfunktionen und Anrufe Kosten eliminiert die Beschleunigung. Zum Beispiel test.h
:Wie erzwinge GHC zu Inline-FFI-Aufrufe?
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 }
Making:
$ gcc -O2 -c test.c
$ ghc -O3 test.o Test.hs
$ ghc --make -O3 test.o Main
$ objdump -d Main > Main.as
schließlich in Main.as
Ich habe callq <inc>
Anweisungen statt wünschenswert inc
‚s.
Sie erwarten, dass GhC eine C-Funktion in den generierten Code einbindet? Dies könnte funktionieren, wenn Sie die Option -via-C verwenden, andernfalls ist es hoffnungslos (da es ghc erfordern würde, den C-Code zu lesen und Code dafür zu generieren). – augustss
Nicht möglich in Abwesenheit von Link-Zeit-Optimierung. Ein (hacky) Ansatz besteht darin, sowohl Haskell als auch C zu LLVM Bitcode zu kompilieren, die .bc Dateien mit 'llvm-link' zu kombinieren, mit' opt' zu optimieren und dann ausführbaren Code mit 'llc' auszugeben. –
@MichailGlushenkov, könnten Sie eine Skizze der Befehlssequenz erstellen? Ich konnte nicht googlen, wie man '.bc' Dateien von Haskell-Code erhält. – leventov