2014-05-16 55 views
3

首先,D如何创建并行foreach(底层逻辑)?D并行循环

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对象),程序永远不会结束。为什么?

回答

5

并行返回一个结构(类型为ParallelForeach),该结构实现了foreach重载的opApply(int delegate(...))

被调用时,结构会向专用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(); 
     } 
    } 
} 

其中workUnitIndexshouldContinue被共享变量和dg是在foreach委托

它之所以是较慢的是将函数传递给所需的开销的仅仅是因为线程在池中并自动访问共享变量。

您的自定义池不关闭很可能你不finish

+0

感谢一个很好的答案关闭线程池的原因。我有另外一个问题。我如何使用(在我的课上重载)opApply?在文档中没有描述oppApply运算符重载。 – Seraph

+0

请参阅http://dlang.org/statement.html#ForeachStatement和http://ddili.org/ders/d.en/foreach_opapply.html –

+0

谢谢,这对我非常有帮助。 – Seraph