事情十这样的,有同事想要统计某些广告的点击,在多线程下运行,可能会同时操作同一个数据项,最早使用一个全局锁,效果不好,现在改成了细粒度锁,每一个数据项一个锁,但还是希望性能更好些。

我的想法是,使用Intel TBB的Atomic,这就避免了使用锁,同时性能也会提升,不过,到底能提升多少还要用数据说话。

1. 不使用锁的情况

#include <iostream>

#include <vector>

#include <pthread.h>

using namespace std;

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)