- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写代码来执行子集乘积:它需要一个元素列表和一个指示变量列表(长度相同)。产品是在树中计算的,这对我们的应用程序至关重要。每个产品都很昂贵,所以我的目标是并行计算树的每个级别,按顺序评估连续的级别。因此,不存在任何嵌套并行性。
我只有一个函数中的 repa 代码,靠近我的整体代码的顶层。请注意,subsetProd 不是一元的。
步骤:
代码:
{-# LANGUAGE TypeOperators, FlexibleContexts, BangPatterns #-}
import System.Random
import System.Environment (getArgs)
import Control.Monad.State
import Control.Monad.Identity (runIdentity)
import Data.Array.Repa as Repa
import Data.Array.Repa.Eval as Eval
import Data.Array.Repa.Repr.Vector
force :: (Shape sh) => Array D sh e -> Array V sh e
force = runIdentity . computeP
chunk :: [a] -> [(a,a)]
chunk [] = []
chunk (x1:x2:xs) = (x1,x2):(chunk xs)
slow_fib :: Int -> Integer
slow_fib 0 = 0
slow_fib 1 = 1
slow_fib n = slow_fib (n-2) + slow_fib (n-1)
testSubsetProd :: Int -> Int -> IO ()
testSubsetProd size seed = do
let work = do
!flags <- replicateM size (state random)
!values <- replicateM size (state $ randomR (1,10))
return $ subsetProd values flags
value = evalState work (mkStdGen seed)
print value
subsetProd :: [Int] -> [Bool] -> Int
subsetProd [!x] _ = x
subsetProd !vals !flags =
let len = (length vals) `div` 2
!valpairs = Eval.fromList (Z :. len) $ chunk vals :: (Array V (Z :. Int) (Int, Int))
!flagpairs = Eval.fromList (Z :. len) $ chunk flags :: (Array V (Z :. Int) (Bool, Bool))
!prods = force $ Repa.zipWith mul valpairs flagpairs
mul (!v0,!v1) (!f0,!f1)
| (not f0) && (not f1) = 1
| (not f0) = v0+1
| (not f1) = v1+1
| otherwise = fromInteger $ slow_fib ((v0*v1) `mod` 35)
in subsetProd (toList prods) (Prelude.map (uncurry (||)) (toList flagpairs))
main :: IO ()
main = do
args <- getArgs
let [numleaves, seed] = Prelude.map read args :: [Int]
testSubsetProd numleaves seed
整个程序是用
编译的ghc -Odph -rtsopts -threaded -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000 -fllvm -optlo-O3
根据these instructions ,在 GHC 7.6.2 x64 上。
我使用运行我的程序(子集)
$> time ./Test 4096 4 +RTS -sstderr -N4
8秒后:
672,725,819,784 bytes allocated in the heap
11,312,267,200 bytes copied during GC
866,787,872 bytes maximum residency (49 sample(s))
433,225,376 bytes maximum slop
2360 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 1284212 colls, 1284212 par 174.17s 53.20s 0.0000s 0.0116s
Gen 1 49 colls, 48 par 13.76s 4.63s 0.0946s 0.6412s
Parallel GC work balance: 16.88% (serial 0%, perfect 100%)
TASKS: 6 (1 bound, 5 peak workers (5 total), using -N4)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.00s ( 0.00s elapsed)
MUT time 497.80s (448.38s elapsed)
GC time 187.93s ( 57.84s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 685.73s (506.21s elapsed)
Alloc rate 1,351,400,138 bytes per MUT second
Productivity 72.6% of total user, 98.3% of total elapsed
gc_alloc_block_sync: 8670031
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 571398
当我增加 -N 参数时,我的代码确实变慢了(-N1 为 7.628 秒,-N2 为 7.891 秒,-N4 为 8.659 秒),但我创建了 0 个 Spark ,这似乎是一个主要嫌疑人至于为什么我没有得到任何并行性。此外,使用大量优化进行编译有助于提高运行时速度,但对并行性没有帮助。
Threadscope 确认没有在 3 个 HEC 上进行认真的工作,但垃圾收集器似乎正在使用所有 4 个 HEC。
那么为什么 Repa 没有产生任何 Spark 呢?我的产品树有 64 个叶子,因此即使 Repa 为每个内部节点生成一个 Spark ,也应该有大约 63 个 Spark 。我觉得这可能与我使用封装并行性的 ST monad 有关,尽管我不太确定为什么这会导致问题。也许 Spark 只能在 IO monad 中创建?
如果是这种情况,有谁知道我如何执行这个树产品,其中每个级别都是并行完成的(不会导致嵌套并行性,这对我的任务来说似乎是不必要的)。总的来说,也许有更好的方法来并行化树产品或更好地利用 Repa。
解释为什么运行时间随着我增加 -N 参数而增加的奖励点,即使没有创建 Spark 。
编辑我将上面的代码示例更改为我的问题的编译示例。程序流程几乎完全符合我的真实代码:我随机选择一些输入,然后对它们进行子集乘积。我现在使用identity monad 。我已经尝试对我的代码进行很多小的更改:是否内联、是否有爆炸模式、使用两个 Repa 列表和 Repa zipWith 与按顺序压缩列表并使用 Repa 映射的变化,等等,这些都没有任何帮助。
即使我遇到this我的示例代码中存在问题,我的实际程序要大得多。
最佳答案
程序没有并行性的主要原因(至少对于您现在的简化和工作而言)是您在 V
表示数组上使用 computeP
,法向量的元素类型并不严格。所以你实际上并没有并行地做任何真正的工作。最简单的修复方法是通过将 force
更改为以下定义,使用未装箱的 U
数组作为结果:
force :: (Shape sh, Unbox e) => Array D sh e -> Array U sh e
force a = runIdentity (computeP a)
我确实记得在您的原始代码中您声称您正在使用未拆箱的复杂数据类型。但真的不可能做到吗?也许您可以将实际需要的数据提取到一些不可装箱的表示形式中?或者使类型成为 Unbox
类的实例?如果没有,您还可以使用以下适用于 V
数组的 force
变体:
import Control.DeepSeq (NFData(..))
...
force :: (Shape sh, NFData e) => Array D sh e -> Array V sh e
force a = runIdentity $ do
r <- computeP a
!b <- computeUnboxedP (Repa.map rnf r)
return r
这里的想法是,我们首先计算 V
数组结构,然后计算 ()
类型的 U
数组通过将 rnf
映射到数组上来从中得到。生成的数组并不有趣,但是 V
数组的每个元素都将在该过程中被强制1。
在我的机器上使用 -N4
时,这些更改都可以将 4096
问题的运行时间从约 9 秒缩短到约 3 秒。
此外,我觉得每一步都在列表和数组之间进行转换很奇怪。为什么不让 subsetProd
接受两个数组?另外,至少对于值来说,使用中间的 V 数组似乎没有必要,您也可以使用 D 数组。但在我的实验中,这些更改并没有对运行时产生显着的有益影响。
Repa从不产生 Spark 。 Haskell 有许多不同的并行方法,而 Spark 是一种在运行时系统中得到特殊支持的特殊机制。但是,只有某些库(例如 parallel
包和 monad-par
包的一个特定调度程序)实际上使用了该机制。然而,雷帕却没有。它在内部使用forkIO
,即线程,但向外部提供纯接口(interface)。因此,没有 Spark 本身就无需担心。
<子>1. 我本来不知道该怎么做,所以我问了 Repa 的作者 Ben Lippmeier。非常感谢 Ben 指出映射 rnf
来生成不同数组的选项,以及 ()
有一个 Unbox
实例>,对我来说。
关于haskell - 并行 Repa 代码不会产生 Spark ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16097418/
我在 Chrome 上做了一些测试,requestAnimationFrame 产生了 61 fps 而 setTimeOut( callback, 0 ) 产生了 233 fps。 如果一个人想要超
当我调试代码时,我发现 GCC 和 Clang 都为 0.0/0.0 产生 nan,这是我所期望的,但 GCC 产生的 nan 将符号位设置为 1,而Clang 将其设置为 0(如果我没记错的话,与
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
我在 R Studio 中有一个时间序列。现在我想计算这个系列的log()。我尝试了以下方法: i <- (x-y) ii <- log(i) 但是我得到以下信息:Warning message: I
我有兴趣了解 JavaScript 的内部结构.我试图阅读 SpiderMonkey 的来源和 Rhino但是绕过我的头是相当复杂的。 我问的原因是:为什么像 (![]+[])[+!![]+[]] 生
我们在 Delphi 中使用标准 TWebbrowser 组件,该组件在内部使用 mshtml.dll。另外,我们使用注册表来确保页面使用新的渲染引擎( Web-Browser-Control-Spe
我必须实现一个序列化/反序列化类,并且我正在使用 System.Xml.Serialization 。我有一些IList类型属性并希望在 IList 中序列化解码属于具有特定区域性信息的列表的所有十进
我有一个 Java 应用程序,它读取包含 SQL 查询的 JSON 文件,并使用 JDBC 在数据库上触发它们。 现在我有 5 万个这样的文件,我需要生成 5 万个独立线程来读取每个文件并将它们上传到
我正在尝试将 TensorFlow 入门页面上的示例线性回归程序调整为二次回归。为此,我只是添加了另一个变量并更改了函数。然而,这似乎会导致 NaN 值。这是我的代码: import numpy as
申请后KernelPCA到我的数据并将其传递给分类器 ( SVC ) 我收到以下错误: ValueError: Input contains NaN, infinity or a value too
这背后的想法是,如果我的数据库中存在登录名(正确的用户名+密码),我将重定向到一个页面,并且在进行此身份验证后,他们可以将消息存储在文本文件中。代码非常简单尽管我不确定为什么会收到 IllegalSt
我有一个返回 log10 值的函数。在将它们转换为正常数字时,出现溢出错误。 OverflowError: (34, 'Numerical result out of range') 我检查了日志值,
nosetests 抛出一个 ImportError,尽管我认为这是一个正确配置的 virtualenv。 ==============================================
我是这个网站的新手,所以如果我做错了什么,我提前道歉。当我尝试使用 kivy-garden 的 ScrollLabel 时,它给了我一个错误。基本上我正在尝试创建一个控制台日志,并且我需要能够在文本框
任何人都对 MDSJ 有任何经验?以下输入仅产生 NaN 结果,我不明白为什么。文档非常稀少。 import mdsj.Data; import mdsj.MDSJ; public class MDS
我有一个非常简单的 scala jcuda 程序,它添加了一个非常大的数组。一切都编译和运行得很好,直到我想从我的设备复制超过 4 个字节到主机。当我尝试复制超过 4 个字节时,我收到 CUDA_ER
我正在使用 Hero 组件在两个页面之间创建动画。Hero 组件用于包装一个 Image 小部件(没问题)和一个 Container 小部件(有问题)。 抛出以下溢出错误: ══╡ EXCEPTIO
我无法理解页面 https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/void 中的这一段: This ope
当在 Angular 中使用不立即触发事件的异步管道时(http 请求或任何有延迟的可观察对象),第一个值为 null为什么会这样?如何避免这种情况? 第一个变化: SimpleChange {
如果一个导入的库生成了一个会 panic 的 goroutine 怎么办?在这种情况下,开发人员无法阻止程序退出。 就像在这段代码中一样,使用延迟恢复调用一个错误的库没有帮助,因为该库正在生成一个 p
我是一名优秀的程序员,十分优秀!