天网基准测试中的TPL样本并不真正平行?

时间:2016-02-18 13:27:06

标签: c# .net parallel-processing task-parallel-library

我发现this suite of benchmarks比较跨语言的并行/分布式处理概念。

我查看了.NET TPL基准测试的代码,发现它有点奇怪并继续调试它。

debugging threads

似乎我们有一个任务与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)。

1 个答案:

答案 0 :(得分:4)

是的,你是对的。所有递归代码在单个线程上同步运行。还有另一个与此并行运行的计算:对ActionBlock中的数组求和。

这不接近代码的描述。