【问题标题】:Intel TBB variable broadcastIntel TBB 变量广播
【发布时间】:2014-01-15 13:11:47
【问题描述】:

我正在使用 Intel TBB 来创建并行的 Eratosthenes 筛子。我已经用 C 语言在 MPI 中完成了这项工作。

所以,我希望我的第一个线程(或任务?)找到一个素数,然后广播到其他线程,以便他们都可以从数组的一部分“交叉”这个素数。

问题是:我找不到方法:

  1. 检测第一个线程或任务。

  2. 让其他人等到第一个线程或任务广播它的素数。

我已经了解如何使用 reduce 等,但我找不到这个。我找到了一个使用一些非常快的 Eratosthenes 算法的示例,但根本没有同步,而且算法不同,我需要并行这个确切的默认算法。

提前致谢!

【问题讨论】:

    标签: multithreading intel tbb sieve-of-eratosthenes


    【解决方案1】:

    我想更好地理解算法,所以我做了一些Googling on "parallel Eratosthenes" and found this,它使用与您的方法类似的语言,但没有很好地解释算法。根据算法的描述,它不太适合像 TBB 这样的基于任务的 API。具体来说,任务不应该阻塞或等待任何事情;它应该在有工作要做时生成,然后运行完成。如果我们将您的算法概念调整为基于任务的方法,那么它将如下所示:

    1. 创建一个向量来保存已知素数。这里不需要并发,因为它不会同时写入。用一个起始集填充它(所有素数都到 100?)创建一个 int 来保存最大的检查数(设置为 100)。
    2. 从最大的检查数字 p+1 到不大于 p^2 的某个数字开始一个 parallel_reduce 数字分区。每个 parallel_reduce 任务都将维护自己的已发现素数向量。 parallel_reduce 会自动将这些任务细分为更小的任务。
    3. 在 parallel_reduce 任务中,每个任务都使用已知素数向量运行串行筛,以消除其范围内的合数,并填充自己的已发现素数向量。
    4. 当 parallel_reduce 连接两个任务时,将所有素数从一个任务的向量复制到另一个任务的向量。
    5. 当您完成一项任务时,您有一个素数向量可以附加到已知素数上。同样,这里不需要并发。
    6. 将最大检查数的 int 更新为您检查的任何内容,然后返回第 2 步,直到获得所有所需的素数。

    所以没有“广播”素数,也没有第一个任务的特殊工作。只有一系列的 parallel_reduce 可以让你得到越来越多的素数。

    更新

    如果您必须在任务之间传递信息,使用 TBB 的方法是使用 tbb::mutex 保护对该数据的访问。

    然而,设计挑战不是如何在任务之间安全地传输数据——挑战是每个任务在等待数据时在做什么?如果答案是“无”,那么您应该不使用任务。任务被设计为运行完成,不应在 tbb::mutex 之类的同步原语上自旋等待或阻塞。如果您可以设计您的任务,以便它们遍历工作并定期检查来自其他任务的新数据以修改其方法,那将很好。同样的迭代和检查新数据方法可以更容易地通过一系列 parallel_reduce 调用建模,如上所述。

    【讨论】:

    • 是的,有升级 Eratosthenes 算法和删除广播等选项。但我的目标不是 Eratosthenes 筛子,目标是解决 Intel TBB 中的同步任务问题。就像 MPI 可以从一个或另一个进程发送某些信息一样,我想对英特尔 TBB 做同样的事情。我想避免在多个任务上完成一次迭代,然后创建另一组任务来进行第二次迭代,我想在任务工作时同步任务。 TBB 中是否有内置机制?并感谢您的回答。
    • 正如我在上面的更新中所解释的,任务不应该被同步,因此 TBB 没有提供这样做的机制。有工作时创建任务,让它们完成并在工作完成时消失。
    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多