Haskell 并行延迟计算
Haskell lazy evaluation in parallelism
如果值 x
在列表中,其中 x
是某个函数
parList
在该列表中被调用(例如 [l,x,l,x]
)
x
计算一次还是两次?
根据我对 Haskell 惰性求值的理解,一旦 x
被求值,就不需要再次求值,因为它会 return 相同的值。但这适用于多线程环境吗?
每当您为计算创建 spark
(这就是 parList
所做的)总有可能
该计算的工作将执行两次。
实际上,这种情况很少发生。基本上有一个竞争条件
在处理火花的线程和主线程之间。
Haskell 通过初始设置变量的值来实现惰性
到 thunk - 本质上是指向计算值的代码的指针。
当要求变量的值时,Haskell 运行s 指向的代码
to by the thunk 并用返回值替换thunk。
如果稍后使用该变量,Haskell 只使用存储的值。
当您并行评估一个变量时,会创建一个 spark 指向
变量。当火花由后台线程处理时
只需要 spark 指向的值。如果火花点
对于 thunk,thunk 是 运行 并用返回值更新。
如果火花指向已评估的值,则什么也不会发生
我们说火花 fizzles.
因此,如果您并行计算 [x,x,x,x,x,x]
这样的列表,一个火花
将为列表的每个元素创建,并且有可能
这些火花中的两个或多个将同时执行。也是
主线程可能会同时评估 x
。
在这种情况下,计算 x
的工作将被重复。
但是,一旦更新了 x
的 thunk,就没有 spark 或主线程
之后开始计算 x
将重新计算 x
.
如果值 x
在列表中,其中 x
是某个函数
parList
在该列表中被调用(例如 [l,x,l,x]
)
x
计算一次还是两次?
根据我对 Haskell 惰性求值的理解,一旦 x
被求值,就不需要再次求值,因为它会 return 相同的值。但这适用于多线程环境吗?
每当您为计算创建 spark
(这就是 parList
所做的)总有可能
该计算的工作将执行两次。
实际上,这种情况很少发生。基本上有一个竞争条件
在处理火花的线程和主线程之间。
Haskell 通过初始设置变量的值来实现惰性 到 thunk - 本质上是指向计算值的代码的指针。 当要求变量的值时,Haskell 运行s 指向的代码 to by the thunk 并用返回值替换thunk。 如果稍后使用该变量,Haskell 只使用存储的值。
当您并行评估一个变量时,会创建一个 spark 指向 变量。当火花由后台线程处理时 只需要 spark 指向的值。如果火花点 对于 thunk,thunk 是 运行 并用返回值更新。 如果火花指向已评估的值,则什么也不会发生 我们说火花 fizzles.
因此,如果您并行计算 [x,x,x,x,x,x]
这样的列表,一个火花
将为列表的每个元素创建,并且有可能
这些火花中的两个或多个将同时执行。也是
主线程可能会同时评估 x
。
在这种情况下,计算 x
的工作将被重复。
但是,一旦更新了 x
的 thunk,就没有 spark 或主线程
之后开始计算 x
将重新计算 x
.