【问题标题】:Multithreading not taking advantage of multiple cores?多线程没有利用多核?
【发布时间】:2010-07-07 01:39:03
【问题描述】:

我的电脑是双核 core2Duo。我已经在我的应用程序的慢速区域实现了多线程,但我仍然注意到 CPU 使用率从未超过 50%,并且在多次迭代后仍然滞后。这是正常的吗?我希望它能让我的 CPU 达到 100%,因为我将它分成 4 个线程。为什么还可以限制在 50%?

谢谢

What am I doing wrong? (multithreading)

对于我的实现,除了我修复了该代码存在的问题

【问题讨论】:

  • 你是如何“实现多线程”的?您如何确定这部分是您应用程序的瓶颈?
  • 可能有些明显,但该进程是否甚至有权使用超过 1 个核心? (签入任务管理器)
  • 是的,这是允许的,基本上我将工作分成 4 份并在多个线程上运行我的算法,我确定了它,因为删除它会使事情变得更快
  • 拥有多个执行线程并不一定会让您的应用程序更快。例如,在false sharing 场景中,添加多个线程会导致性能急剧下降。
  • 老兄,您需要提供更多信息。所有这些问题暂时符合条件的是“你真的 100%确定它是Core 2 Duo!!???”

标签: c++ c windows multithreading


【解决方案1】:

查看您的代码,您在紧密循环中进行了大量分配——在每次迭代中,您动态分配两个双元素向量,然后将它们推回结果向量(从而复制那些向量);最后一次推回偶尔会导致重新分配和复制向量内容。

堆分配相对较慢,即使您的实现对小块使用快速、固定大小的分配器也是如此。在最坏的情况下,通用分配器甚至可能使用全局锁;如果是这样,它将消除您可能从多线程中获得的任何收益,因为每个线程将花费大量时间等待堆分配。

当然,分析会告诉您堆分配是否限制了您的性能,或者它是否是其他因素。我会提出两个具体的建议来减少你的堆分配:

  • 由于内部向量的每个实例都有两个元素,您应该考虑使用std::array(或std::tr1::arrayboost::array); array“容器”不为其元素使用堆分配(它们像 C 数组一样存储)。
  • 由于您大致知道要放入结果向量中的元素数量,因此您可以在插入这些元素之前reserve() 为这些元素提供足够的空间。

【讨论】:

    【解决方案2】:

    根据您的描述,我们几乎没有什么可做的,但是,让我看看是否可以提供帮助:

    1. 您已经实现了一个基于锁的系统,但是您没有明智地使用第二个、第三个或第四个线程的资源,因为它们需要的实体一直处于锁定状态。 (这是我首先要研究的一个非常真实和明显的领域)
    2. 您实际上并没有使用多个线程。不知何故,在某个地方,那些其他线程甚至没有被启动或初始化。 (听起来很愚蠢,但我以前做过)

    首先查看这些区域。

    【讨论】:

    • 调用栈说有 4 个线程在运行,而且没有一个线程访问过同一个元素。
    • @user146780:我不确定您如何通过查看调用堆栈来计算正在运行的线程数。您愿意详细说明吗?
    • 好吧,我添加了一个巨大的 for 循环并将 cpu 提高到 100%,但正如 James McNellis 刚刚告诉我的那样,我认为我做了太多堆分配
    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 2023-03-27
    • 2015-12-17
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2021-05-10
    相关资源
    最近更新 更多