首先,D如何创建并行foreach(底层逻辑)?
int main(string[] args)
{
int[] arr;
arr.length = 100000000;
/* Why it is working?, it's simple foreach which working with
reference to int from arr, parallel function return ParallelForeach!R
(ParallelForeach!int[]), but I don't know what it is.
Parallel function is part od phobos library, not D builtin function, then what
kind of magic is used for this? */
foreach (ref e;parallel(arr))
{
e = 100;
}
foreach (ref e;parallel(arr))
{
e *= e;
}
return 0;
}
第二,为什么它比简单的foreach慢? 最后,如果我创建自己的taskPool(并且不使用全局taskPool对象),程序永远不会结束。为什么呢?
答案 0 :(得分:5)
parallel返回一个实现ParallelForeach
foreach重载的结构(类型为opApply(int delegate(...))
)。
当调用struct时,向私有submitAndExecute
提交并行函数,该私有scope(failure)
{
// If an exception is thrown, all threads should bail.
atomicStore(shouldContinue, false);
}
while (atomicLoad(shouldContinue))
{
immutable myUnitIndex = atomicOp!"+="(workUnitIndex, 1);
immutable start = workUnitSize * myUnitIndex;
if(start >= len)
{
atomicStore(shouldContinue, false);
break;
}
immutable end = min(len, start + workUnitSize);
foreach(i; start..end)
{
static if(withIndex)
{
if(dg(i, range[i])) foreachErr();
}
else
{
if(dg(range[i])) foreachErr();
}
}
}
将相同的任务提交给池中的所有线程。
然后这样做:
workUnitIndex
其中shouldContinue
和dg
是共享变量,而{{1}}是foreach代理
它变慢的原因仅仅是因为将函数传递给池中的线程并原子地访问共享变量所需的开销。
您的自定义池未关闭的原因可能是您没有使用finish
关闭线程池