【问题标题】:Fine grained multithreading - how much should a worker task do?细粒度的多线程——一个工作任务应该做多少?
【发布时间】:2009-08-26 12:35:19
【问题描述】:

我正在使用 work_pile 模式,因此线程始终在运行并在信号量上等待传入的新函数指针 + 队列中的数据。这就是苹果营销人员现在所说的 Grand Central Dispatch 并宣传为新的切片面包。

我只是想知道如何确定将一个短任务分成两个更短的任务是否有用。有什么规则可以让我判断是否值得排队一个新对象?

【问题讨论】:

标签: c multithreading


【解决方案1】:

两个可能的答案:

  • 视情况而定。
  • 对其进行基准测试。

我更喜欢第二个。

无论如何,如果两个任务总是一个接一个地运行(即,顺序地),我认为拆分它们没有任何好处。

【讨论】:

  • 基准测试并不容易,只有实现了才能做到。当我应该开始考虑拆分时,我想要一份清单。我什至不知道线程激活平均要花费多少,它需要纳秒还是微秒?如果我将算法的多个步骤排队,那么只有一个信号量计数器递减和一个互斥锁,比如 100 个周期 + 缓存未命中?
  • 我要补充一点,一个重要因素也是 CPU/内核的数量以及任务分配给它们的方式。尽管理论上您可以从可用内核的数量中抽象出来,但我很确定只有基准测试才能准确回答您的问题。
  • @mouvicel:基准测试的局限性在于它只能为您提供特定问题的答案,并且不一定提供关于如何在稍微不同的情况下调整以获得最佳性能的深入见解。这就是为什么我们希望有一些理论见解,然后可以用于自动调整。
【解决方案2】:

多任务处理的限制是您拥有多少个内核以及有多少算法是并发的。各种类型的开销,包括锁定,可以减少并发量,降低甚至逆转多任务处理的好处。这就是为什么当有独立的、长时间运行的任务时它最有效的原因。话虽如此,只要开销不影响性能提升,即使是一个很短的任务在内核之间进行分配也是值得的。

【讨论】:

  • 工作堆模式背后的想法是您可以从可用内核的数量中抽象出来。
  • 对,对于 CPU 密集型活动,您可能会设置 n+1 个线程从输入队列中读取,其中 n 是内核数。对于 I/O 绑定的,您可能需要更多。
  • 好的,我对它进行了更多研究,听起来操作系统正在负责池中的线程数。我想这很方便,但我不确定它是如何决定调整的。当 I/O 阻塞时,n+1 启发式会严重失败。
  • 是的,但是由于 IO 阻塞时的操作系统消息,它可以将一个新线程分配给线程池。它动态地平衡 n+1 与只有主管才能拥有的所有智慧。马贝苹果是对的,这是新的切片面包。
  • 我承认这听起来很有趣,但我不确定它是否需要操作系统干预。我也不确定在另一个块时添加线程是否完全正确。考虑一个充满 I/O 绑定函数的管道的情况,在这种情况下,这样的算法会很快导致数十个线程同时唤醒并发现自己颠簸。我需要多考虑一下。
【解决方案3】:

简短的回答是您需要考虑资源 + 工作负载 + 基准测试。

以下是一些事情可能会崩溃的方式:

  1. 您有空闲线程吗?工作负载是否足够大,以至于一个线程需要很长时间才能完成,以至于另一个线程挂起等待重新分配(即线程多于工作)?
  2. 你有足够的工作吗?整个任务是否完成得如此之快以至于不值得考虑额外的线程?请记住,增加多线程确实会增加一些(有时)少量但可衡量的开销。
  3. 您有可用的资源吗?你有更多的线程要给吗?您是否有空闲的 CPU 周期?

因此,简而言之,我会说您需要在输入之前进行思考。如果您已经拥有完全可用的代码,那就像银行里的钱一样。是否值得投入更多时间来提高该代码的生产力,或者投资回报率会不会太低(或负数!)?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2010-09-22
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多