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 解决方法
你提到了复制构造函数.我假设这些也从堆中分配内存?
在多个线程中分配堆内存是一个很大的错误. 标准分配器可能是单个池锁定实现.您需要不使用堆内存(堆栈分配),或者需要线程优化堆分配器. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |