【发布时间】:2015-02-16 22:43:34
【问题描述】:
问题
您好,我正在使用加速库创建一个应用程序,允许用户以交互方式调用处理图像的函数,这就是我使用 ghc api 基于和扩展 ghci 的原因。
问题在于,当从 shell 运行编译后的可执行文件时,计算在 100 毫秒(略小于 80 毫秒)内完成,而在 ghci 中运行相同的编译代码则需要超过 100 毫秒(平均多于 140 毫秒)完成。
资源
示例代码+执行日志: https://gist.github.com/zgredzik/15a437c87d3d8d03b8fc
说明
首先:测试是在编译 CUDA 内核之后运行的(编译本身增加了 2 秒,但事实并非如此)。
当从 shell 运行编译后的可执行文件时,计算在 10 毫秒内完成。 (shell first run 和 second shell run 传递了不同的参数以确保数据没有缓存在任何地方)。
当尝试从 ghci 运行相同的代码并摆弄输入数据时,计算时间超过 100 毫秒。我知道解释代码比编译代码慢,但我在 ghci 会话中加载相同的编译代码并调用相同的顶级绑定 (packedFunction)。我已明确键入它以确保它是专用的(与使用 SPECIALIZED pragma 的结果相同)。
但是,如果我在 ghci 中运行 main 函数(即使在连续调用之间使用 :set args 更改输入数据),计算时间确实不到 10 毫秒。
用ghc -o main Main.hs -O2 -dynamic -threaded编译Main.hs
我想知道开销从何而来。有人对为什么会发生这种情况有任何建议吗?
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
当我编译并执行它需要 0,09s 来完成。
$ 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
但是当我预编译它并在解释器中运行它需要 0,25s
$ ghc -O2 Main.hs -c -dynamic
$ ghci Main
ghci> main
Array (Z) [1000001.0]
0.258224s
【问题讨论】:
-
您能打开分析并获取报告吗?
-
你的意思是:downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/…?我会尽快尝试的。
-
我在
Data.Array.Accelerate.CUDA.run中注入了一些时间测量代码,我注意到当acclerate库加载到ghci 时,run的执行速度比在可执行文件中使用时慢3 倍。我尝试添加以下编译指示但没有效果。{-# SPECIALISE run :: Acc (Array DIM2 Double) -> (Array DIM2 Double) #-} {-# SPECIALISE run :: Acc (Array DIM2 Float) -> (Array DIM2 Float) #-}。我们可以为 ghci 优化这个 run 函数吗? -
我已经更新了要点 - 添加了分析报告 (main.prof)
-
@ChristianConkle,我从这里 stackoverflow.com/questions/27881725/… 尝试了您的测试,并将此重写规则注入到加速 cuda 库中 - 结果:
isOptimised=True,但代码仍然很慢。
标签: performance haskell profiling ghci accelerate-haskell