【问题标题】:Tasks parallelism slower than normal execution?任务并行性比正常执行慢?
【发布时间】:2012-01-18 16:23:03
【问题描述】:

我有点困惑,因为当我使用这段代码时:

catalog.Elements = GetElements(myProvider.Elements);
catalog.Programs = GetPrograms(myProvider.Programs);
catalog.Details = GetDetails(myProvider.Details);

我有 4 秒。

当我尝试使用任务 (.NET 4.0) 时:

Task<List<Element>> elementsTask = Task.Factory.StartNew<List<Element>>(
    delegate { 
        return GetElements(myProvider.Elements); 
    });
Task<List<Program>> programsTask = Task.Factory.StartNew<List<Program>>(
    delegate { 
        return GetPrograms(myProvider.Programs); 
    });
Task<List<Detail>> detailsTask = Task.Factory.StartNew<List<Detail>>(
    delegate { 
        return GetDetails(myProvider.Details); 
    });

catalog.Elements = elementsTask.Result;
catalog.Programs = programsTask.Result;
catalog.Details = detailsTask.Result;

我有 6 秒。

我不使用任务并行的时候速度更快是正常的吗?

谢谢

【问题讨论】:

  • 你是如何测量时间的?
  • 带秒表类
  • 这些方法使用什么? sql server?
  • 我有一个奔腾双核 CPU,我正在控制台项目中执行它。
  • 这一切都取决于这些任务实际完成了多少工作,以及它的 CPU 或 IO 是否出现瓶颈

标签: c# .net c#-4.0 task


【解决方案1】:

并行有多种形式。这完全取决于底层硬件和您试图“并行化”的问题。

在您的情况下,您可能会在 CPU 级别出现资源争用。几核?共享缓存?计算昂贵的例程?非常轻的例程,所以线程的开销超过了收益?例程是否访问共享状态?

很多问题。基本上,不要假设并行代码运行得更快。

抱歉,这不是对您的性能问题的解决方案,但要做到这一点,您需要解释每个例程在做什么。

从好的方面来说,我会乐观地假设您已经做了一件好事并分析了两段代码。您的分析告诉您“并行化”(注意,不是瘫痪 :-P)代码不会产生任何好处,因此可以避免使用更简单的同步代码。

实际上,回答您的问题:是的,这可能是正常的,但需要了解您尝试并行化的问题。不要将此示例作为 TPL 预期性能的指标。当涉及到我使用异步代码做出的错误或假设时,我总是吃不起的馅饼......

【讨论】:

  • 在这段代码中,我只是用我已经加载的内容准备新对象,所以不需要调用数据库,只进行数据操作
  • @ahikaz 根据硬件的不同,如果运行时决定让出不同的线程,线程将相互竞争 CPU 时间。在多核系统上,这通常是看不到的。在单核系统上,您可以看到为了给线程时间片工作而完成的上下文切换。这种切换成本。这在计算密集型任务上更为明显。
  • @DanielA.White 是的,但我猜这都是基于 OP 各种 cmets 的本地性能。
  • 我尝试在我的方法中只使用我之前加载的数据创建新对象。当然,我不会以它作为任务执行的例子,但我认为我会得到更好的执行时间或与顺序模式相同
【解决方案2】:

您应该使用ThreadPool.QueueUserWorkItem 方法,而不是仅仅通过盲目地创建新任务来在两个内核上堆叠线程,因为这已经进行了一些性能调整,例如线程回收和负载平衡。

【讨论】:

    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多