我在一台有 32 个 CPU(1 个插槽,每个插槽 16 个内核,每个内核 2 个线程)的机器上运行 Ubuntu。
我有一个包含 ~100-1000 个对象的 std::vector,我正在尝试并行化一个 for 循环,该循环从 vector 中的每个对象读取数据并写入文件以记录每个对象的状态。每个对象都有一个文件。我试过 omp_set_num_threads(8)
并发现大约 8 个线程是最佳选择。如果我增加或减少线程数,运行时性能将会降低。鉴于我有 32 个可用的 CPU,我不确定为什么将线程数增加到 8 个以上会降低运行时性能。我知道之前已经问过很多类似的问题,但我似乎无法找到解决我的特定问题的方法。
#include <algorithm>
#include <experimental/filesystem>
#include <omp.h>
namespace fs = std::experimental::filesystem;
void log() {
omp_set_num_threads(8);
// Log all object states
if(this->logstate){
#pragma omp parallel for
for(auto i = vObject.begin(); i < vObject.end(); ++i) {
fs::path filename = (*i)->get_filename();
std::ofstream OutputFile;
OutputFile.open(filename, std::ios::app);
OutputFile << std::setw(30) << (*i)->get_EPOCH() << std::setw(20) << std::scientific << std::setprecision(5) << (*i)->get_state() << std::endl;
OutputFile.close();
}
}
}
如有任何想法或建议,我们将不胜感激。
最佳答案
I am running Ubuntu on a machine with 32 CPUs (1 socket, 16 cores per socket, 2 threads per core).
线程不是 CPU。核心甚至不是真正的 CPU;每个内核都可以独立执行代码,但它们都共享一条内存总线和各种其他资源。
因此,您有 32 个线程在 16 个内核上运行,所有线程都共享一条总线。在某些时候会有争用某些东西,这意味着很多线程必须等待。更多线程 -> 更多竞争 -> 更多等待。
现在,我们都可以对资源争用的可能位置做出有根据的猜测——是文件系统、内存总线还是其他什么?但是我们对您的系统以及可能发生的其他事情知之甚少,因此这可能毫无意义。分析在更多线程上运行的代码以查看它在哪里进行大量等待可能会提供一些答案。请记住,这些答案可能特定于您当前的情况;如果您更改需要为每个对象完成的计算工作,或更改收集输出的方式等,这可能会影响最佳位置。
关于c++ - 为什么使用更多线程会导致运行时间变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58377555/