zoukankan      html  css  js  c++  java
  • 【读书笔记】 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
    ", 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.

  • 相关阅读:
    C++中使用stringstream进行类型转换操作
    代理模式
    观察者模式 VS 责任链模式
    10.模板方法模式
    2.里氏替换原则
    单一职责原则
    规格模式
    策略模式的扩展——策略枚举
    策略模式 VS 桥梁模式
    原型模式【下】
  • 原文地址:https://www.cnblogs.com/superniaoren/p/3350747.html
Copyright © 2011-2022 走看看