【发布时间】:2019-10-14 13:08:56
【问题描述】:
我在具有 32 个 CPU(1 个插槽,每个插槽 16 个内核,每个内核 2 个线程)的机器上运行 Ubuntu。
我有一个包含 ~100-1000 个对象的 std::vector,我正在尝试并行化一个 for 循环,该循环从向量中的每个对象读取数据并写入文件以记录每个对象的状态。每个对象都有一个文件。我玩过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();
}
}
}
任何想法或建议将不胜感激。
【问题讨论】:
-
只是一个疯狂的猜测:如果线程数超过 8 个,那么同时您将有超过 8 个“进程”写入磁盘。可能会造成一些瓶颈
-
我猜你只能同时写入 8 个文件。
-
一个只有 100-1000 个对象的向量足够小,可以在不注意的情况下迭代单线程。即使对每个对象进行单线程文件处理也会非常快。尤其是考虑到可能来自多个线程竞争同一设备的 IO 争用。
-
创建和销毁线程是有代价的。在线程之间切换是有代价的。线程之间的同步是有代价的。添加线程不是可以加快速度的神奇银弹。如果问题中没有足够的并行性来克服使用线程的开销,那么您很可能通过添加更多线程来减慢代码的速度。
-
你没有给出任何时间度量。如果整个过程花费的时间少于几秒钟,那么由于 Some dude 和 Jesper 解释的原因,您将开始失去添加超过 8 个线程的过程。
标签: c++ multithreading performance ubuntu openmp