Haskell 发散计算超时
Haskell Timeout diverging computation
我正在尝试在 Haskell 中编写一个安全的超时评估函数。代码如下
import System.Timeout
compute, compute' :: Int -> Int
compute i = sum [1..300000 + i]
compute' i = last $ repeat i
timedComp :: Int -> a -> IO (Maybe a)
timedComp timeLeft toCompute =
timeout timeLeft go
where
go = toCompute `seq` return toCompute
main = do
res <- timedComp 10000 (compute 0)
print res
res' <- timedComp 10000 (compute' 0)
print res'
(我知道我只评价WHNF。)
当我 运行 main 时,我只得到一个 Nothing 输出,然后程序挂起。我试图编译和 运行 程序多线程但它没有帮助。在 GHC 7.6.3 和 7.8.3 上都试过。有什么建议吗?
Haskell 线程的 GHC 实现存在一个限制:上下文切换仅在分配期间发生。因此,根本不执行任何分配的紧密循环可以阻止调度程序 运行,切换到其他线程。
这是这样的例子之一:compute' i = last $ repeat i
看起来好像是在分配列表单元格,但不幸的是 GHC 能够将其优化为一个简单的无限循环,删除所有分配——GHC Core 看起来大致是 f x = f x
。这会触发调度程序的缺点。
Reid Barton 建议选择 -fno-omit-yields
解决此问题。这样会导致GHC优化不了那么多
我正在尝试在 Haskell 中编写一个安全的超时评估函数。代码如下
import System.Timeout
compute, compute' :: Int -> Int
compute i = sum [1..300000 + i]
compute' i = last $ repeat i
timedComp :: Int -> a -> IO (Maybe a)
timedComp timeLeft toCompute =
timeout timeLeft go
where
go = toCompute `seq` return toCompute
main = do
res <- timedComp 10000 (compute 0)
print res
res' <- timedComp 10000 (compute' 0)
print res'
(我知道我只评价WHNF。)
当我 运行 main 时,我只得到一个 Nothing 输出,然后程序挂起。我试图编译和 运行 程序多线程但它没有帮助。在 GHC 7.6.3 和 7.8.3 上都试过。有什么建议吗?
Haskell 线程的 GHC 实现存在一个限制:上下文切换仅在分配期间发生。因此,根本不执行任何分配的紧密循环可以阻止调度程序 运行,切换到其他线程。
这是这样的例子之一:compute' i = last $ repeat i
看起来好像是在分配列表单元格,但不幸的是 GHC 能够将其优化为一个简单的无限循环,删除所有分配——GHC Core 看起来大致是 f x = f x
。这会触发调度程序的缺点。
Reid Barton 建议选择 -fno-omit-yields
解决此问题。这样会导致GHC优化不了那么多