【发布时间】:2020-05-16 06:03:01
【问题描述】:
我是多线程编程的新手,我知道之前有人在 SO 上问过几个类似的问题,但是我想得到一个特定于我的代码的答案。
我有两个要循环的对象向量(v1 和 v2),根据它们是否满足某些条件,将这些对象添加到单个向量中,如下所示:
非多线程案例
std::vector<hobj> validobjs;
int length = 70;
for(auto i = this->v1.begin(); i < this->v1.end() ;++i) {
if( !(**i).get_IgnoreFlag() && !(**i).get_ErrorFlag() ) {
hobj obj(*i, length);
validobjs.push_back(hobj);
}
}
for(auto j = this->v2.begin(); j < this->v2.end() ;++j) {
if( !(**j).get_IgnoreFlag() && !(**j).get_ErrorFlag() ) {
hobj obj(*j, length);
validobjs.push_back(hobj);
}
}
多线程案例
std::vector<hobj> validobjs;
int length = 70;
#pragma omp parallel
{
std::vector<hobj> threaded1; // Each thread has own local vector
#pragma omp for nowait firstprivate(length)
for(auto i = this->v1.begin(); i < this->v1.end() ;++i) {
if( !(**i).get_IgnoreFlag() && !(**i).get_ErrorFlag() ) {
hobj obj(*i, length);
threaded1.push_back(obj);
}
}
std::vector<hobj> threaded2; // Each thread has own local vector
#pragma omp for nowait firstprivate(length)
for(auto j = this->v2.begin(); j < this->v2.end() ;++j) {
if( !(**j).get_IgnoreFlag() && !(**j).get_ErrorFlag() ) {
hobj obj(*j, length);
threaded2.push_back(obj);
}
}
#pragma omp critical // Insert local vectors to main vector one thread at a time
{
validobjs.insert(validobjs.end(), threaded1.begin(), threaded1.end());
validobjs.insert(validobjs.end(), threaded2.begin(), threaded2.end());
}
}
在非多线程情况下,我执行操作所花费的总时间比多线程情况快 4 倍左右(~1.5s vs ~6s)。
我知道 #pragma omp critical 指令会影响性能,但由于我事先不知道 validobjs 向量的大小,我不能依赖按索引随机插入。
所以问题:
1) 这种操作适合多线程吗?
2) 如果 1) 是 - 多线程代码看起来合理吗?
3) 我可以做些什么来提高性能以使其比无线程情况更快?
附加信息:
- 上述代码嵌套在一个更大的代码库中,该代码库执行 10,000 - 100,000 次迭代(此循环未使用多线程)。我知道生成线程也会产生性能开销,但据我所知,这些线程一直保持活动状态,直到每次迭代都再次执行上述代码
-
omp_set_num_threads设置为 32(我在 32 核机器上)。 - Ubuntu,gcc 7.4
干杯!
【问题讨论】:
-
我们可能需要更多代码才能继续。
v1和v2是什么?您能否发布更多代码,以便您的多线程代码易于执行? -
你如何测量时间?
-
@MarkLoeser 确定 - Intel® Xeon(R) Gold 6130 CPU @ 2.10GHz × 32 w/64gb RAM
-
为什么有两个变量 threaded1 和 2?您是否希望 thread1 只被一个线程触及?
-
@Gilles 我正在使用 std::chrono::system_clock::now();在代码块之前和之后并将差异累积到静态变量
标签: c++ multithreading optimization openmp