ProblemRóżnica w wydajności skompilowany kod przyspieszyć biegła od ghci i powłoki
Witam, używam przyspieszyć biblioteki do tworzenia aplikacji, pozwalając użytkownikowi na interaktywne funkcje przetwarzania obrazów zadzwonić, dlatego jestem bazując na i rozszerzając ghci używając ghc api.
Problem polega na tym, że podczas uruchamiania skompilowanego pliku wykonywalnego z powłoki obliczenia wykonywane są poniżej 100ms (nieco mniej niż 80), podczas gdy uruchamianie tego samego skompilowanego kodu w ghci zajmuje ponad 100ms (średnio nieco ponad 140) skończyć.
Resources
kod + wykonanie przykładowe kłody: https://gist.github.com/zgredzik/15a437c87d3d8d03b8fc
Opis
Przede wszystkim: badania były pobiegł za jądro CUDA został skompilowany (kompilacja sama dodany dodatkowy 2 sekundy, ale tak nie jest).
Podczas wykonywania skompilowanego pliku wykonywalnego z powłoki obliczenia są wykonywane w mniej niż 10 ms. (shell first run
i second shell run
mają przekazane różne argumenty, aby upewnić się, że dane nie zostały w pamięci podręcznej nigdzie).
Podczas próby uruchomienia tego samego kodu z ghci i manipulowania danymi wejściowymi, obliczenia zajmują 100 ms. Rozumiem, że zinterpretowany kod jest wolniejszy niż skompilowany, ale ładuję ten sam skompilowany kod w ramach sesji ghci i wywołuję to samo powiązanie najwyższego poziomu (packedFunction
). Napisałem go jawnie, aby upewnić się, że jest wyspecjalizowany (takie same wyniki jak użycie SPECJALIZOWANEJ pragma).
Jednak obliczenia zajmują mniej niż 10 ms, jeśli uruchomię funkcję main
w ghci (nawet przy zmianie danych wejściowych na :set args
między kolejnymi połączeniami).
skompilował Main.hs
z ghc -o main Main.hs -O2 -dynamic -threaded
zastanawiam gdzie napowietrznej pochodzi. Czy ktoś ma jakieś sugestie, dlaczego tak się dzieje?
Uproszczona wersja przykład wysłana przez remdezx:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Array.Accelerate as A
import Data.Array.Accelerate.CUDA as C
import Data.Time.Clock (diffUTCTime, getCurrentTime)
main :: IO()
main = do
start <- getCurrentTime
print $ C.run $ A.maximum $ A.map (+1) $ A.use (fromList (Z:.1000000) [1..1000000] :: Vector Double)
end <- getCurrentTime
print $ diffUTCTime end start
Kiedy skompilować i wykonać to trwa 0,09s, aby zakończyć.
$ ghc -O2 Main.hs -o main -threaded
[1 of 1] Compiling Main (Main.hs, Main.o)
Linking main ...
$ ./main
Array (Z) [1000001.0]
0.092906s
Ale kiedy precompile go i uruchomić w tłumacza trwa 0,25s
$ ghc -O2 Main.hs -c -dynamic
$ ghci Main
ghci> main
Array (Z) [1000001.0]
0.258224s
Czy możesz włączyć profilowanie i otrzymać raport? –
masz na myśli tutaj: https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/profiling.html? Spróbuję najszybciej. –
Wpadłem trochę kodu pomiarowego czasu do 'Data.Array.Accelerate.CUDA.run' i zauważyłem, że kiedy' aklerate' biblioteka jest ładowana do ghci, 'run' wykonuje 3 razy wolniej niż wtedy, gdy jest użyte w pliku wykonywalnym . Próbowałem dodać kolejne pragmy, ale bez efektu. '{- # SPECIALIZE run :: Acc (Array DIM2 Double) -> (Array DIM2 Double) # -} {- Uruchom # SPECIALIZE :: Acc (Array DIM2 Float) -> (Array DIM2 Float) # -}' . Czy możemy zoptymalizować jakoś tę funkcję uruchamiania dla ghci? – remdezx