注意:这是我在此网站上发布的第一篇文章,但我已经广泛搜索,无法找到解决问题的方法。 我写了一个程序,它主要测试一个数字向量的所有排列,以找到我定义的最佳序列。当然,即使对于小输入来说,计算数字排列也是非常耗时的,所以我试图通过使用多线程来加快速度。并行运行的多线程C++程序使用矢量<thread>和.join()
这里是一个小样本,其复制的问题:
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,并且除了一个共享对象(它们全都通过指针引用)之外,它们都有自己的执行工作所需的数据副本。因为我lock_guard用于从互斥使它所以只有一个线程可以一次更新bestSolution
private:
Solution* bestSolution;
此共享的数据是不容易受到数据竞争条件。
换句话说,为什么我的CPU在我的多线程程序中几乎100%运行,它使用了系统中可用的多个线程?
我可以随时更新这篇文章,如果需要更多的信息。
您可能需要[mcve],并且您的共享对象看起来高度怀疑是数据竞赛 –
@PasserBy共享对象不应受数据竞争条件的影响。 –
代码还不完整,根据经验,有人应该能够复制粘贴某些内容并查看结果。这并不是说你应该把所有东西都放在这里,这意味着你应该以某种方式嘲笑'解决方案'和它的访问,这仍然可以复制问题。如果您后来意识到问题与“解决方案”的工作方式有关,那么您可能已经解决了这个问题。 –