【问题标题】:Multithreaded C++ Program Not Running In Parallel Using vector<thread> and .join()多线程 C++ 程序未使用 vector<thread> 和 .join() 并行运行
【发布时间】:2017-07-04 03:23:48
【问题描述】:

注意:这是我在此网站上发表的第一篇文章,但我进行了广泛搜索,但无法找到解决问题的方法。 我编写了一个程序,它基本上测试数字向量的所有排列,以找到我定义的最佳序列。当然,即使是小的输入,计算数字的排列也是非常耗时的,所以我试图通过使用多线程来加快速度。


这是一个复制问题的小样本:

class TaskObject {
public:
    void operator()() {
        recursiveFunc();
    }
private:
    Solution *bestSolution; //Shared by every TaskObject, but can only be accessed by one at a time
    void recursiveFunc() {
        if (base_case) { 
            //Only part where shared object is accessed
            //base_case is rarely reached
            return;
        }
        recursiveFunc();
    }
};

void runSolutionWithThreads() {
    vector<thread> threads(std::thread::hardware_concurrency());
    vector<TaskObject> tasks_vector(std::thread::hardware_concurrency());
    updateTasks(); //Sets parameters that intialize the first call to recursiveFunc
    for (int q = 0; q < (int)tasks_vector.size(); ++q) {
        threads[q] = std::thread(tasks_vector[q]);
    }
    for (int i = 0; i < (int)threads.size(); ++i) {
        threads[i].join();
    }
}

我以为这将使所有线程能够并行运行,但我可以看到使用 Visual Studio 中的性能分析器和 Windows 任务管理器的高级设置,一次只运行 1 个线程。在可以访问 4 个线程的系统上,CPU 限制在 25%。 每次运行时我都会得到正确的输出,因此算法逻辑没有问题。工作尽可能均匀地分布在所有任务对象中。很少发生与共享数据的冲突。使用线程池的程序实现总是以接近 100% 的速度运行。

提交给线程的对象不会打印到 cout,并且除了它们都通过指针引用的一个共享对象之外,它们都有自己的数据副本来执行它们的工作。

private:
    Solution* bestSolution;

此共享数据不易受到数据竞争条件的影响,因为我使用互斥锁中的 lock_guard 来制作它,因此一次只有一个线程可以更新 bestSolution。

换句话说,我的多线程程序使用系统中可用的线程数,为什么我的 CPU 没有以接近 100% 的速度运行?

如果需要,我可以随时更新这篇文章,提供更多信息。

【问题讨论】:

  • 您可能需要minimal reproducible example,而您的共享对象看起来非常怀疑是数据竞争
  • @PasserBy 共享对象不应受到数据竞争条件的影响。
  • 代码还不完整,经验法则是有人应该能够复制粘贴某些内容并查看您的结果。这并不是说你应该把所有的东西都塞进去,这意味着你应该模拟Solution 及其以某种方式访问​​它仍然可以复制问题。如果您后来意识到问题与 Solution 的工作方式有关,那么您可能已经解决了问题。

标签: c++ multithreading concurrency parallel-processing thread-synchronization


【解决方案1】:

在调试您的应用程序时,使用调试器“中断所有”线程。然后使用调试线程窗口检查每个线程以查看每个线程正在执行的位置。您可能会发现只有一个线程正在执行代码,而其余的都被阻塞在一个正在运行的线程所持有的互斥体上。

如果你展示一个更完整的代码示例,它可以提供很大帮助。

【讨论】:

  • 我更新了帖子,指出与共享数据的冲突很少发生。在调试器中,似乎所有线程都以大致相同的速度工作,但在我的 4 线程系统上,CPU 在性能分析器中的利用率为 25%。我知道这肯定有错误,因为当我使用线程池实现运行程序时,我发现程序几乎总是处于 100% 的 CPU 利用率。
猜你喜欢
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多