英特尔TBB变量广播

时间:2014-01-15 13:11:47

标签: multithreading intel tbb sieve-of-eratosthenes

我正在使用英特尔TBB来创建平行的Eratosthenes筛。我已经用C语言在MPI中完成了这个。

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

问题是:我找不到办法:

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

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

  3. 我已经明白我如何使用reduce等,但我无法找到它。我找到了一个非常快速的Eratosthenes算法的例子,但根本没有同步,算法也不同,我需要将这个确切的默认值并行。

    提前致谢!

1 个答案:

答案 0 :(得分:1)

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

  1. 创建一个向量来保存已知质数。这里不需要并发,因为它不会同时写入。用起始器集填充它(所有素数最多为100?)创建一个int来保存最大的校验数(设置为100)。
  2. 从最大的已检查数 p +1开始并行数字分区的并行减少到不大于 p ^ 2的某个数字。每个parallel_reduce任务都将维护自己的已发现素数向量。 parallel_reduce会自动将这些任务细分为较小的任务。
  3. 在parallel_reduce任务中,每个任务都使用已知素数向量运行序列筛,以消除其范围内的复合数,并填充其自己的已发现质数向量。
  4. 当parallel_reduce加入两个任务时,将所有素数从一个任务的向量复制到另一个任务的向量。
  5. 当你完成一项任务时,你有一个素数向量可以附加到已知的素数上。同样,这里不需要并发。
  6. 将最大的已检查号码的int更新为您检查的内容,然后返回步骤2,直到您获得所需的所有素数。
  7. 所以没有“广播”素数,也没有任何特殊工作的第一项任务。只有一系列parallel_reduces可以让你获得越来越多的素数。

    <强>更新

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

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