我发现this suite of benchmarks比较跨语言的并行/分布式处理概念。
我查看了.NET TPL基准测试的代码,发现它有点奇怪并继续调试它。
似乎我们有一个任务与Main任务并行运行,如果我理解正确的话,只会对所有同步和递归结果进行异步减少(聚合)。
源代码为here:
long limit = 1000000;
var x3 = Task.Run( () => skynetTpl( 0, limit, 10 ) );
...
static void skynetTplRecursion( ITargetBlock<long> src, long num, long size, long div )
{
if( size == 1 )
{
src.SendAsync( num );
return;
}
for( var i = 0; i < div; i++ )
{
var sub_num = num + i * ( size / div );
skynetTplRecursion( src, sub_num, size / div, div );
}
}
static async Task<long> skynetTpl( long num, long size, long div )
{
BatchBlock<long> source = new BatchBlock<long>( 1024 );
long sum = 0;
ActionBlock<long[]> actAggregate = new ActionBlock<long[]>( vals => sum += vals.Sum(),
new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 1, SingleProducerConstrained = true } );
source.LinkTo( actAggregate, new DataflowLinkOptions() { PropagateCompletion = true } );
skynetTplRecursion( source, num, size, div );
source.Complete();
await actAggregate.Completion;
return sum;
}
我的理解是否正确?如果没有,为什么?
更新:
存储库作者所述代码的目标:
创建一个演员(goroutine,无论如何),它会产生10个新演员,每个演员产生10个演员等等,直到在最后一级创建了一百万个演员。然后,它们中的每一个都返回它的序数(从0到999999),它们在前一级别上求和并向上游发送,直到到达根演员。 (答案应该是499999500000)。
答案 0 :(得分:4)
是的,你是对的。所有递归代码在单个线程上同步运行。还有另一个与此并行运行的计算:对ActionBlock
中的数组求和。
这不接近代码的描述。