C++ tbb::atomic
原创
©著作权归作者所有:来自51CTO博客作者软件工程小施同学的原创作品,请联系作者获取转载授权,否则将追究法律责任
事情十这样的,有同事想要统计某些广告的点击,在多线程下运行,可能会同时操作同一个数据项,最早使用一个全局锁,效果不好,现在改成了细粒度锁,每一个数据项一个锁,但还是希望性能更好些。
我的想法是,使用Intel TBB的Atomic,这就避免了使用锁,同时性能也会提升,不过,到底能提升多少还要用数据说话。
1. 不使用锁的情况
int v = 0; void * tf( void * args) { for ( int i = 0;i < 100000;i++) { v += 1; } return NULL; } int main() { pthread_t tid; vector<pthread_t> vp; for ( int i = 0;i < 100;i++) { pthread_create(&tid, NULL, tf, NULL); vp.push_back(tid); } for ( int i = 0;i < 100;i++) { pthread_join(vp[i], NULL); } cout<<v<<endl; return 0; } |
意料之内,很快,但结果不对
2706056 real 0m0.038s user 0m0.127s sys 0m0.005s |
2. 换用mutex保护
#include <iostream> \#include <pthread.h> #include <vector> using namespace std; pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER; int v; void * tf( void * args) { for ( int i = 0;i < 100000;i++) { pthread_mutex_lock(&mt); v += 1; pthread_mutex_unlock(&mt); } return NULL; } int main() { pthread_t tid; vector<pthread_t> vp; for ( int i = 0;i < 100;i++) { pthread_create(&tid, NULL, tf, NULL); vp.push_back(tid); } for ( int i = 0;i < 100;i++) { pthread_join(vp[i], NULL); } cout<<v<<endl; return 0; } |
结果正确了,但太慢了
10000000 real 0m25.782s user 0m3.929s sys 0m25.601s |
3. 用Atomic替换下吧
#include <iostream> #include <tbb/atomic.h> #include <pthread.h> #include <vector> using namespace std; typedef tbb::atomic< int > ATOMINT; ATOMINT v; void * tf( void * args) { for ( int i = 0;i < 100000;i++) { v += 1; } return NULL; } int main() { pthread_t tid; vector<pthread_t> vp; for ( int i = 0;i < 100;i++) { pthread_create(&tid, NULL, tf, NULL); vp.push_back(tid); } for ( int i = 0;i < 100;i++) { pthread_join(vp[i], NULL); } cout<<v<<endl; return 0; } |
结果准而快
10000000 real 0m0.222s user 0m0.817s sys 0m0.007s |
结论:TBB的Atomic性能卓越,对于POD数据,能用Atomic,还是用Atomic吧
p.s
我是在Mac OS X上测试的,x86_64
javascript:void(0)