Tôi đã thực hiện mô-đun C nhỏ để cải thiện hiệu suất, nhưng GHC không trực tiếp chức năng ngoại tuyến, và chi phí cuộc gọi loại bỏ gia tốc. Ví dụ, test.h
:Làm cách nào để buộc GHC thực hiện các cuộc gọi FFI nội tuyến?
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 }
Làm:
$ gcc -O2 -c test.c
$ ghc -O3 test.o Test.hs
$ ghc --make -O3 test.o Main
$ objdump -d Main > Main.as
Cuối cùng, trong Main.as
Tôi có callq <inc>
hướng dẫn thay vì mong muốn inc
's.
Bạn mong đợi ghc để inline một hàm C trong mã được tạo ra của nó? Điều này có thể làm việc nếu bạn sử dụng tùy chọn -via-C, nếu không nó sẽ vô vọng (vì nó sẽ yêu cầu ghc đọc mã C và tạo mã cho nó). – augustss
Không thể khi không có tối ưu hóa thời gian liên kết. Một cách tiếp cận (hacky) để thử là biên dịch cả bit Haskell và C thành LLVM, kết hợp các tệp .bc với 'llvm-link', tối ưu hóa bằng' opt' và sau đó phát ra mã thực thi với 'llc'. –
@MikhailGlushenkov, bạn có thể viết một bản phác thảo tạo chuỗi lệnh không? Tôi không thể tìm ra cách để lấy các tệp '.bc' từ mã haskell. – leventov