博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TBB之concurrent_hash_map
阅读量:4058 次
发布时间:2019-05-25

本文共 2756 字,大约阅读时间需要 9 分钟。

Intel TBB 提供高并发的容器类,Windows或者Linux线程能使用这些容器类或者和基于task编程相结合(TBB)。

一个并发容器允许多线程同时对容器访问和更改条例,典型的C++STL容器类不允许 并发更新,尝试并行更改他们引起恶化容器。STL容器能使用互斥锁来包装,目的让他们安全访问,通过只让一个线程同时操作一个容器,但是这种方式消除了并行,限制了并行提速。

Intel TBB提供的容器有更高水准的并发性,通过以下方法:

  • Fine-grained locking:只通过锁需要锁的部分,在容器上实现多线程操作,一旦多线程访问不同部分,他们能同步进行。
  • Lock-free techniques:改正其他干扰线程的影响。

注意高并发容器是有代价的,他们典型的有更高的消耗比STL容器,对高并发容器操作比STL容器消耗更多,因此,当使用高并发容器比STL容器提速的时候,他们是优于串行的性能。

concurrent_hash_map

concurrenthashmap<Key,T,HashCompare> 是一个hash表,允许并行访问,表是一个从Key到类型T的映射,类型HashCompare定义怎样hash一个Key和怎样比较2个Key。

下面的例子建立一个concurrent_hash_map,这个Key是字符串,对应的数据是矩阵Data中字符串出现的次数。

#include "tbb/concurrent_hash_map.h"#include "tbb/blocked_range.h"#include "tbb/parallel_for.h"#include 
using namespace tbb;using namespace std;// Structure that defines hashing and comparison operations for user'stype.struct MyHashCompare { static size_t hash( const string& x ) { size_t h = 0; for( const char* s = x.c_str(); *s; ++s ) h = (h*17)^*s; return h; } //! True if strings are equal static bool equal( const string& x, const string& y ) { return x==y; }};// A concurrent hash table that maps strings to ints.typedef concurrent_hash_map
StringTable;// Function object for counting occurrences of strings.struct Tally { StringTable& table; Tally( StringTable& table_ ) : table(table_) {} void operator()( const blocked_range
range ) const { for( string* p=range.begin(); p!=range.end(); ++p ) { StringTable::accessor a; table.insert( a, *p ); a->second += 1; } }};const size_t N = 1000000;string Data[N];void CountOccurrences() {// Construct empty table.StringTable table;// Put occurrences into the tableparallel_for( blocked_range
( Data, Data+N, 1000 ), Tally(table) );// Display the occurrencesfor( StringTable::iterator i=table.begin(); i!=table.end(); ++i ) printf("%s %d\n",i->first.c_str(),i->second);}

concurrenthashmap 扮演一个类型 std::pair<constKey,T> 元素的容器,当访问一个容器元素时,你对更新它或者读取它感兴趣,模板类concurrent_hash_map支持这2个目的,对应类accessor和const_accessor,其担当智能指针,accessor表示更新(write)访问,一旦它指向一个元素,所有其他尝试寻找这个表的key都会被阻止,直到accessor被完成。const_accessors是类似的,除了只表示读访问,多const_accessors能同时指向相同的元素,在频繁的读但是很少更新的情况下,这个特点极大的改善并行情形。

方法find和insert采用accessor或者const_accessor作为一个参数,告诉concurrent_hash_map是否你要求更新或者只读访问,一旦这个方法返回,直到访问结束,accessor或者const_accessor才会被销毁,因为对元素的访问阻止其他线程,所以尽可能的缩减accessor或者const_accessor生命周期,为了这么做,我们在内部块中声明它,尽可能在块结束前释放这个accessor,下面的例子是重写循环体,使用release结束accessor的生命周期:

StringTable accessor a;for( string* p=range.begin(); p!=range.end(); ++p ) {    table.insert( a, *p );    a->second += 1;    a.release();}

方法remove(key)也能同时操作,它隐式请求写访问,因此,在删除这个Key之前,它等待其他现存key上的访问结束。

转载地址:http://qimci.baihongyu.com/

你可能感兴趣的文章
【leetcode】Candy(python)
查看>>
【leetcode】Clone Graph(python)
查看>>
【leetcode】Sum Root to leaf Numbers
查看>>
【leetcode】Pascal's Triangle II (python)
查看>>
java自定义容器排序的两种方法
查看>>
如何成为编程高手
查看>>
本科生的编程水平到底有多高
查看>>
AngularJS2中最基本的文件说明
查看>>
从头开始学习jsp(2)——jsp的基本语法
查看>>
使用与或运算完成两个整数的相加
查看>>
备忘:java中的递归
查看>>
DIV/CSS:一个贴在左上角的标签
查看>>
Solr及Spring-Data-Solr入门学习
查看>>
Vue组件
查看>>
python_time模块
查看>>
python_configparser(解析ini)
查看>>
selenium学习资料
查看>>
<转>文档视图指针互获
查看>>
从mysql中 导出/导入表及数据
查看>>
HQL语句大全(转)
查看>>