Concurrency D任务池等待,直到所有任务完成

Concurrency D任务池等待,直到所有任务完成,concurrency,parallel-processing,task,d,wait,Concurrency,Parallel Processing,Task,D,Wait,这与我先前的问题有关: 假设您有一段代码,它由两个连续的代码块a和B组成,其中B依赖于a。这在编程中非常常见。A和B都包含一个循环,其中每个迭代可以并行运行: double[] array = [ ... ]; // has N elements // A for (int i = 0; i < N; i++) { job1(array[i]); // new task } // wait for all job1's to be done // B for (int i =

这与我先前的问题有关:

假设您有一段代码,它由两个连续的代码块a和B组成,其中B依赖于a。这在编程中非常常见。A和B都包含一个循环,其中每个迭代可以并行运行:

double[] array = [ ... ]; // has N elements

// A
for (int i = 0; i < N; i++)
{
    job1(array[i]); // new task
}

// wait for all job1's to be done

// B
for (int i = 0; i < N; i++)
{
    job2(array[i]); // new task
}
double[]数组=[…];//有N个元素
//A
对于(int i=0;i

B只能在A完成时执行。如何等到A的所有任务完成后再执行B?

我假设您使用的是std.parallelism?我写了std.parallelism,所以我会让你参与设计决策。在std.parallelism的一些beta中实际上有一个
join
函数。它等待所有任务完成,然后关闭任务池。我把它拿走了,因为我意识到它没用

原因是,如果您手动创建一组O(N)
task
对象以在某个范围内进行迭代,那么您就误用了库。您应该改用并行foreach循环,它在将控制释放回调用线程之前自动联接。你的例子是:

foreach(ref elem; parallel(array)) {
    job1(elem); 
}

foreach(ref elem; parallel(array)) {
    job2(elem);
}

在这种情况下,
job1
job2
不应启动新任务,因为并行foreach循环已经使用了足够的任务来充分利用所有CPU核心。

我可以理解您的观点。然而,如果我们想使用foreach迭代那些不那么直接的东西,该怎么办?如果要迭代奇数索引,该怎么办?我是否需要构建一个新阵列,以便使用foreach?有一个scopedTask几乎满足了我的需要,除了它的作用域是迭代,而不是整个循环…@Daevius:如果你想迭代奇数索引,你可以使用std.range.stride或foreach(I;parallel(std.range.iota(1,array.length,2)).std.parallelism是在假设std.algorithm和std.range中的高阶范围将提供这种灵活性的情况下创建的,而不必在std.parallelism的设计中明确计划。是的,由于范围创建的许多设施,这是一个整洁的设计。使用我的四核2D FFT算法:),谢谢。顺便问一下,iota真的与希腊字母iota有关吗^^@戴维乌斯,一点也不。这个名字来源于C++的
iota
函数,因为它基本上做了相同的事情。然而,这个名字实际上与它的实际用途无关。我不知道为什么选择C++。很多人不喜欢这个名字,因为它真的没有意义,但它与C++是一致的,而且是值得记忆的。