加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 从STL容器并行读取

发布时间:2020-12-16 10:15:50 所属栏目:百科 来源:网络整理
导读:从多个并行线程读取STL容器是安全的.但是,表现很糟糕.为什么? 我创建了一个小对象,它在multiset中存储了一些数据.这使得构造函数相当昂贵(在我的机器上大约有5个usecs.)我在大型多集中存储了数十万个小对象.处理这些对象是一项独立的业务,因此我在多核机器
从多个并行线程读取STL容器是安全的.但是,表现很糟糕.为什么?

我创建了一个小对象,它在multiset中存储了一些数据.这使得构造函数相当昂贵(在我的机器上大约有5个usecs.)我在大型多集中存储了数十万个小对象.处理这些对象是一项独立的业务,因此我在多核机器上运行的线程之间拆分工作.每个线程从大型多集合中读取所需的对象,并对其进行处理.

问题是来自大型多重集的读取并不是并行进行的.看起来一个线程中的读取会阻塞另一个线程中的读取.

下面的代码是我能做到的最简单的代码,但仍然显示问题.首先,它创建一个包含100,000个小对象的大型多重集,每个小对象都包含自己的空多集.然后它将串联两次调用multiset复制构造函数,然后再并行调用两次.

分析工具显示串行拷贝构造函数大约需要0.23秒,而并行分析构建器需要两倍的时间.不知何故,并行副本互相干扰.

// a trivial class with a significant ctor and ability to populate an associative container
class cTest
{
    multiset<int> mine;
    int id;
public:
    cTest( int i ) : id( i ) {}
    bool operator<(const cTest& o) const { return  id < o.id;  }
};
// add 100,000 objects to multiset
void Populate( multiset<cTest>& m )
{
    for( int k = 0; k < 100000; k++ )
    {
        m.insert(cTest(k));
    }
}
// copy construct multiset,called from mainline
void Copy( const multiset<cTest>& m )
{
    cRavenProfile profile("copy_main");
    multiset<cTest> copy( m );
}
// copy construct multiset,called from thread
void Copy2( const multiset<cTest>& m )
{
    cRavenProfile profile("copy_thread");
    multiset<cTest> copy( m );
}
int _tmain(int argc,_TCHAR* argv[])
{
    cRavenProfile profile("test");
    profile.Start();

    multiset<cTest> master;

    Populate( master );

    // two calls to copy ctor from mainline
    Copy( master );
    Copy( master );

    // call copy ctor in parrallel
    boost::thread* pt1 = new boost::thread( boost::bind( Copy2,master ));
    boost::thread* pt2 = new boost::thread( boost::bind( Copy2,master ));

    pt1->join();
    pt2->join();

    // display profiler results
    cRavenProfile print_profile;

    return 0;
}

这是输出

Scope   Calls       Mean (secs)     Total
      copy_thread        2      0.472498        0.944997
        copy_main        2      0.233529        0.467058

解决方法

你提到了复制构造函数.我假设这些也从堆中分配内存?

在多个线程中分配堆内存是一个很大的错误.

标准分配器可能是单个池锁定实现.您需要不使用堆内存(堆栈分配),或者需要线程优化堆分配器.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读