C++ 多线程比无线程C++;
我是多线程编程的新手,我知道之前有人问过几个类似的问题,但是我想得到一个特定于我代码的答案 我有两个要循环的对象向量(v1和v2),根据它们是否满足某些条件,将这些对象添加到单个向量,如下所示: 非多线程情况C++ 多线程比无线程C++;,c++,multithreading,optimization,openmp,C++,Multithreading,Optimization,Openmp,我是多线程编程的新手,我知道之前有人问过几个类似的问题,但是我想得到一个特定于我代码的答案 我有两个要循环的对象向量(v1和v2),根据它们是否满足某些条件,将这些对象添加到单个向量,如下所示: 非多线程情况 std::vector<hobj> validobjs; int length = 70; for(auto i = this->v1.begin(); i < this->v1.end() ;++i) { if( !(**i).get_Ignore
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());
}
}
std::vector validobjs;
整数长度=70;
对于(自动i=this->v1.begin();iv1.end();++i){
如果(!(**i.get_IgnoreFlag()&&(**i.get_ErrorFlag()){
hobj obj(*i,长度);
有效推回(hobj);
}
}
对于(自动j=this->v2.begin();jv2.end();++j){
如果(!(**j.get_IgnoreFlag()&&(**j.get_ErrorFlag()){
hobj obj(*j,长度);
有效推回(hobj);
}
}
多线程案例
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());
}
}
std::vector validobjs;
整数长度=70;
#pragma-omp并行
{
std::vector threaded1;//每个线程都有自己的本地向量
#nowait firstprivate的pragma omp(长度)
对于(自动i=this->v1.begin();iv1.end();++i){
如果(!(**i.get_IgnoreFlag()&&(**i.get_ErrorFlag()){
hobj obj(*i,长度);
螺纹1.推回(obj);
}
}
std::vector threaded2;//每个线程都有自己的本地向量
#nowait firstprivate的pragma omp(长度)
对于(自动j=this->v2.begin();jv2.end();++j){
如果(!(**j.get_IgnoreFlag()&&(**j.get_ErrorFlag()){
hobj obj(*j,长度);
螺纹2.推回(obj);
}
}
#pragma omp critical//将局部向量一次插入一个线程到主向量
{
插入(validobjs.end(),threaded1.begin(),threaded1.end());
插入(validobjs.end(),threaded2.begin(),threaded2.end());
}
}
在非多线程情况下,我执行操作所花费的总时间大约是多线程情况下的4倍(1.5秒vs 6秒)
我知道#pragma omp critical指令对性能有影响,但由于我事先不知道validobjs向量的大小,因此我无法依靠索引随机插入
因此,问题是:
1)这种操作适合多线程吗?
2)如果是1)-多线程代码看起来合理吗?
3)我能做些什么来提高性能,使其比无线程的情况更快吗?
其他信息:
- 上面的代码嵌套在一个更大的代码库中,该代码库执行10000-100000次迭代(此循环不使用多线程)。我知道生成线程也会带来性能开销,但正如我所知,这些线程一直保持活动状态,直到每次迭代都再次执行上述代码
设置为32(我在一台32核的机器上)omp\u set\u num\u threads
- Ubuntu,gcc 7.4
您可以使用同步将元素添加到单个向量中。我不擅长多线程,但我会尝试一下: 这种操作适合多线程吗 我会说是的。特别是如果你有巨大的数据集,你可以进一步分割它们,并行运行任意数量的过滤操作。但这取决于要处理的数据量,线程创建和同步不是免费的 正如线程版本末尾的合并一样 多线程代码看起来合理吗 我认为让每个线程处理独立数据是正确的 我能做些什么来提高性能,使其比无线程的情况更快 我认为有几点可能会提高性能:
validobjs.reserve(v1.size() + v2.size());
然后合并validobjs.resize(v1.size() + v2.size());
1
写入x
,线程2向索引x+1
写入validobjs.size()-1
尽管我不确定这是完全合法还是不明确的行为您还可以考虑使用
std::list
(链表)。连接链表或删除元素是在固定的时间内进行的,但是添加元素要比使用保留内存的std::vector
稍微慢一点
这就是我的想法,我希望其中有一些有用的东西。我们可能需要更多的代码来继续。什么是
v1
和v2
?您能否再发布一点代码,使多线程代码易于执行?如何测量时间?@MarkLoeser sure-Intel®Xeon(R)Gold 6130 CPU@2.10GHz×32 w/64gb RAM为什么有两个线程化变量1和2?您是否希望threaded1