在D中,如何在不使用TaskPool.reduce的情况下有效地在并行foreach中聚合结果?

Joh*_*tte 3 d

通常在D中,我想写一些类似于:

int result = 0;
foreach(someclass c; parallel(someclass_array)){
    result += somefunction(c);
} 
Run Code Online (Sandbox Code Playgroud)

在某些情况下,我可以将其重写为:

TaskPool.reduce!("a+b")(TaskPool.map!(somefunction)(c);
Run Code Online (Sandbox Code Playgroud)

但在其他情况下,这是不可能的,例如:

int result = 0;
someotherclass d;
int otherArg = 5;
foreach(someclass c; parallel(someclass_array)){
    result += d.somefunction(c, otherArg);
} 
Run Code Online (Sandbox Code Playgroud)

这将无法工作,因为某些函数将作为委托传递给map(以支持otherArg),但是委托目前不会与D中的这些指针混合使用.

我真正喜欢的是一些写作方式:

int result = 0;
foreach(someclass c; parallel(someclass_array)){
    int tmp = somefunction(c);
    ... //something to indicate that this section is atomic
    result += tmp;
    ... //end of atomic section.
} 
Run Code Online (Sandbox Code Playgroud)

我看到D有信号量,但使用它们似乎过于笨重.我也试过atomicOp!("+ ="),但似乎未定义.是否有惯用的D方式来做到这一点?

Vla*_*eev 5

您可以使用synchronized块语句.

int result = 0;
foreach(someclass c; parallel(someclass_array)){
    int tmp = somefunction(c);
    synchronized result += tmp;
} 
Run Code Online (Sandbox Code Playgroud)