【读书笔记】 spinlock, mutex and rwlock 的性能比较

原文的地址在http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/

还有一些相关资料,在这里:

https://computing.llnl.gov/tutorials/pthreads/

http://linux.die.net/man/3/pthread_rwlock_tryrdlock

http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_rwlock_init.html

作者在文中对于spinlock和mutex进行了比较,但是还有rwlock呢,他没有比较,那么测试代码如下,比较一下这三个锁:

 

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>
#include <sys/time.h>
#include <list>
#include <pthread.h>
 
#define LOOPS 5000000
   
using namespace std;
    
list<int> the_list;
     
#ifdef USE_SPINLOCK
pthread_spinlock_t spin_lock;
#elif USE_RWLOCK
pthread_rwlock_t rw_lock;
#else
pthread_mutex_t mutex_lock;
#endif
 
//Get the thread id
pid_t gettid() { return syscall( __NR_gettid ); }
  
void *consumer(void *ptr){
    int i;
    printf("Consumer TID %lun", (unsigned long)gettid());
          
    while (1){
#ifdef USE_SPINLOCK
        pthread_spin_lock(&spin_lock);
#elif USE_RWLOCK
        pthread_rwlock_wrlock( &rw_lock );
//        pthread_rwlock_rdlock( &rw_lock );
#else
        pthread_mutex_lock(&mutex_lock);
#endif
        if (the_list.empty()){
#ifdef USE_SPINLOCK
             pthread_spin_unlock(&spin_lock);
#elif USE_RWLOCK
             pthread_rwlock_unlock( &rw_lock);
#else
            pthread_mutex_unlock(&mutex_lock);
#endif
            break;
        }
         
        i = the_list.front();
        the_list.pop_front();
         
#ifdef USE_SPINLOCK
        pthread_spin_unlock(&spin_lock);
#elif  USE_RWLOCK
        pthread_rwlock_unlock( &rw_lock);
#else
        pthread_mutex_unlock(&mutex_lock);
#endif
    }
    return NULL;
}

int main(void){
    pthread_t tid_0, tid_1;

    struct timeval tv_0, tv_1;
#ifdef USE_SPINLOCK
    pthread_spin_init( &spin_lock, 0 );
#elif USE_RWLOCK
    pthread_rwlock_init( &rw_lock, NULL);
#else
    pthread_mutex_init( &mutex_lock, NULL );
#endif
    //init the lsit
    int i;
    for(i=0; i<LOOPS; i++){
        the_list.push_back(i);
    }
    gettimeofday(&tv_0, NULL);
    pthread_create(&tid_0, NULL, consumer, NULL);
    pthread_create(&tid_1, NULL, consumer, NULL);
    //
    pthread_join(tid_0, NULL);
    pthread_join(tid_1, NULL);
    //
    gettimeofday(&tv_1, NULL);
    timersub(&tv_1, &tv_0, &tv_1);

    printf("timing result: secs=%d, usec=%d\n", tv_1.tv_sec, tv_1.tv_usec);
#ifdef USE_SPINLOCK
    pthread_spin_destroy(& spin_lock );
#elif USE_RWLOCK
    pthread_rwlock_destroy( &rw_lock);
#else
    pthread_mutex_destroy(&mutex_lock);
#endif
    return 0;
}

这里的测试代码是基本采用了原文的代码,然后添加进入了对于rwlock的测试代码;

各个锁性能测试结果如下:

$lsb_release -a

Distributor ID: Ubuntu
Description:    Ubuntu 12.04.3 LTS
Release:        12.04
Codename:       precise
$time ./spinlock

Consumer TID 11602nConsumer TID 11603ntiming result: secs=0, usec=585267

real    0m1.017s
user    0m1.512s
sys     0m0.060s

$time ./mutex

Consumer TID 11586nConsumer TID 11585ntiming result: secs=1, usec=22265

real    0m5.783s
user    0m1.068s
sys     0m1.244s

$time ./rwlock

Consumer TID 11596nConsumer TID 11595ntiming result: secs=1, usec=381404

real    0m1.864s
user    0m1.436s
sys     0m1.516s

time 命令的输出格式简单介绍一下:

S: Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
U: Total number of CPU-seconds that the process used directly (in user mode), in seconds.

P: Percentage of the CPU that this job got.  This is just user + system times divided by the total running time. It also prints a percent‐age sign.

 

posted on 2013-10-04 10:06  馒头山小八路  阅读(1849)  评论(0编辑  收藏  举报

导航