我在几本OpenMP教程中读到,您所生成的任务不应多于线程数。 For example:“启动的任务不要超过可用线程,这意味着在封闭的并行区域中可用。”
假设我们要遍历二叉树,可以并行遍历节点的子树,并且我们的机器具有四个核心。根据上面的建议,我们在根目录生成两个任务,一个任务在左侧,一个任务在右侧子树。在这两个任务中,我们生成两个嵌套任务,每个子树一个。现在,我们有四个任务,因此我们不再将它们分开。
但是,如果四个子树的大小不同,则某些内核将不得不等待。负载均衡继续进一步拆分并生成16个任务会更好吗?即使我们只有四个核心?
通常生成一个不多于线程的任务是一个好建议吗?或者这是胡扯吗?
答案 0 :(得分:2)
您可以使用比线程更多的任务,这是任务的主要目的。是的,使用多于线程的任务将有助于负载均衡。
所引用的文章对我来说似乎很关键,尽管他的批评有一些优点,但我不同意否定性。我不会深入探讨他针对OpenMP任务提出的每一个观点。是的,与任何并行性范例或C / C ++ / Fortran一样,有很多方法可以使您轻松应对OpenMP任务。
在执行带有任务的树算法时,我担心的一件事是任务创建的开销。尽管任务比线程更轻量,但它们不是免费的。如果树上的叶子节点只有几个指令,并且为每个节点创建一个任务,那么您将有巨大的开销。
您可以使用omp task if (depth < theshold)
,但这仍然会在更深的层中留下一些开销。为了完全避免这种情况,您必须实现遍历功能的两个版本,一个始终调用串行一个的序列号和一个有条件地调用任务或串行一个任务的任务。这也可以提供更好的优化。您应该选择阈值,以使最小task duration >> task overhead
和任务数足以避免负载不平衡(取决于变化)。