我已经实现了一种迭代算法,其中每次迭代涉及一个先序树遍历(有时称为向下累积)和一个后序树遍历(向上累积)。每次访问每个节点都涉及计算和存储信息以供下一次访问使用(无论是在随后的后序遍历还是在随后的迭代中)。
在先序遍历期间,只要它和根之间的所有节点都已处理,就可以独立地处理每个节点。处理后,每个节点需要将一个元组(具体而言是两个浮点数)传递给其每个子节点。在后序遍历中,只要其所有子树(如果有)已经被处理,就可以独立地处理每个节点。处理后,每个节点需要将一个单一的浮点数传递给其父节点。
树的结构在算法期间是静态且不变的。但是,在向下遍历过程中,如果传递的两个浮点数都变为零,则此节点下面的整个子树无需进行处理,并且此节点的向上遍历可以开始。(必须保留子树,因为在此节点上的后续迭代中,传递的浮点数可能会变为非零值,并且遍历将恢复)。
每个节点的计算强度在整个树中是相同的。每个节点上的计算都很简单:只需要对一个与节点子数相等的数字列表执行几个求和和乘除运算。
被处理的树是不平衡的:一个典型节点会有2个叶子加上0-6个额外的子节点。因此,将树分成一组相对平衡的子树并不明显(至少对我来说)。此外,这些树旨在消耗所有可用的RAM:我可以处理的更大的树越多,就越好。
我的串行实现在我的小测试树上达到每秒约1000次迭代;对于“真正”的树,我预计它可能会减慢一个数量级(或更多?)。鉴于该算法需要至少1亿次迭代(可能高达10亿)才能达到可接受的结果,我希望并行化算法以利用多个核心。我没有任何并行编程经验。
考虑到我的算法性质,推荐什么样的并行化模式?
在先序遍历期间,只要它和根之间的所有节点都已处理,就可以独立地处理每个节点。处理后,每个节点需要将一个元组(具体而言是两个浮点数)传递给其每个子节点。在后序遍历中,只要其所有子树(如果有)已经被处理,就可以独立地处理每个节点。处理后,每个节点需要将一个单一的浮点数传递给其父节点。
树的结构在算法期间是静态且不变的。但是,在向下遍历过程中,如果传递的两个浮点数都变为零,则此节点下面的整个子树无需进行处理,并且此节点的向上遍历可以开始。(必须保留子树,因为在此节点上的后续迭代中,传递的浮点数可能会变为非零值,并且遍历将恢复)。
每个节点的计算强度在整个树中是相同的。每个节点上的计算都很简单:只需要对一个与节点子数相等的数字列表执行几个求和和乘除运算。
被处理的树是不平衡的:一个典型节点会有2个叶子加上0-6个额外的子节点。因此,将树分成一组相对平衡的子树并不明显(至少对我来说)。此外,这些树旨在消耗所有可用的RAM:我可以处理的更大的树越多,就越好。
我的串行实现在我的小测试树上达到每秒约1000次迭代;对于“真正”的树,我预计它可能会减慢一个数量级(或更多?)。鉴于该算法需要至少1亿次迭代(可能高达10亿)才能达到可接受的结果,我希望并行化算法以利用多个核心。我没有任何并行编程经验。
考虑到我的算法性质,推荐什么样的并行化模式?