几种线程本地存储变量和普通变量的性能比较

God一直致力于研究高并发服务端的开发,这次要优化的是libGod库中的线程本地存储变量,线程本地存储变量访问非常频繁,优化后库的性能应该会提高不少。已知的线程本地存储方法有boost中的thread_specific_ptr类,gcc中的__thread关键字,pthread中的pthread_getspecific函数。这次测试这3中本地存储以及普通变量之间的性能差别,代码如下:

 
  1. #include <iostream>   
  2. #include <stdio.h>   
  3. #include <pthread.h>   
  4. #include <boost/thread/thread.hpp>   
  5. #include <boost/thread/tss.hpp>   
  6.   
  7. using namespace std;   
  8.   
  9. class C {   
  10. public:   
  11.     C(int a) {   
  12.         m_a = a;   
  13.         printf("C() %d ", m_a);   
  14.     }   
  15.     ~C() {   
  16.         printf("~C() %d ", m_a);   
  17.     }   
  18.   
  19. private:   
  20.     int m_a;   
  21. };   
  22.   
  23. #define TM 3   
  24.   
  25. #if TM == 1   
  26.     boost::thread_specific_ptr<C> pc;   
  27.     const char *testType = "boost";   
  28. #elif TM == 2   
  29.     __thread C *pc;   
  30.     const char *testType = "__thread";   
  31. #elif TM == 3   
  32.     pthread_key_t pc;   
  33.     const char *testType = "pthread";   
  34. #else   
  35.     C *pc;   
  36.     const char *testType = "normal";   
  37. #endif   
  38.   
  39. void boostthreadFunc() {   
  40. #if TM == 1   
  41.     pc.reset(new C(10));   
  42. #elif TM == 2   
  43.     pc = new C(20);   
  44. #elif TM == 3   
  45.     if (pthread_key_create(&pc, NULL)) {   
  46.         cout << "pthread_key_create" << endl;   
  47.         return;   
  48.     }   
  49.     if (pthread_setspecific(pc, new C(30))) {   
  50.         cout << "pthread_setspecific" << endl;   
  51.         return;   
  52.     }   
  53. #else   
  54.     pc = new C(20);   
  55. #endif   
  56.     int switches = 5000000;   
  57.     int i = switches;   
  58.     struct timeval tm_start, tm_end;   
  59.     gettimeofday(&tm_start, NULL);   
  60.     while (i--) {   
  61. #if TM == 1   
  62.         C *c1 = pc.get();   
  63.         C *c2 = pc.get();   
  64.         C *c3 = pc.get();   
  65.         C *c4 = pc.get();   
  66.         C *c5 = pc.get();   
  67.   
  68.         C *c6 = pc.get();   
  69.         C *c7 = pc.get();   
  70.         C *c8 = pc.get();   
  71.         C *c9 = pc.get();   
  72.         C *c10 = pc.get();   
  73.   
  74.         C *c11 = pc.get();   
  75.         C *c12 = pc.get();   
  76.         C *c13 = pc.get();   
  77.         C *c14 = pc.get();   
  78.         C *c15 = pc.get();   
  79.   
  80.         C *c16 = pc.get();   
  81.         C *c17 = pc.get();   
  82.         C *c18 = pc.get();   
  83.         C *c19 = pc.get();   
  84.         C *c20 = pc.get();   
  85.   
  86.         C *c21 = pc.get();   
  87.         C *c22 = pc.get();   
  88.         C *c23 = pc.get();   
  89.         C *c24 = pc.get();   
  90.         C *c25 = pc.get();   
  91.   
  92.         C *c26 = pc.get();   
  93.         C *c27 = pc.get();   
  94.         C *c28 = pc.get();   
  95.         C *c29 = pc.get();   
  96.         C *c30 = pc.get();   
  97.   
  98.         C *c31 = pc.get();   
  99.         C *c32 = pc.get();   
  100.         C *c33 = pc.get();   
  101.         C *c34 = pc.get();   
  102.         C *c35 = pc.get();   
  103.   
  104.         C *c36 = pc.get();   
  105.         C *c37 = pc.get();   
  106.         C *c38 = pc.get();   
  107.         C *c39 = pc.get();   
  108.         C *c40 = pc.get();   
  109.   
  110. #elif TM == 2   
  111.         C *c1 = pc;   
  112.         C *c2 = pc;   
  113.         C *c3 = pc;   
  114.         C *c4 = pc;   
  115.         C *c5 = pc;   
  116.   
  117.         C *c6 = pc;   
  118.         C *c7 = pc;   
  119.         C *c8 = pc;   
  120.         C *c9 = pc;   
  121.         C *c10 = pc;   
  122.   
  123.         C *c11 = pc;   
  124.         C *c12 = pc;   
  125.         C *c13 = pc;   
  126.         C *c14 = pc;   
  127.         C *c15 = pc;   
  128.   
  129.         C *c16 = pc;   
  130.         C *c17 = pc;   
  131.         C *c18 = pc;   
  132.         C *c19 = pc;   
  133.         C *c20 = pc;   
  134.   
  135.         C *c21 = pc;   
  136.         C *c22 = pc;   
  137.         C *c23 = pc;   
  138.         C *c24 = pc;   
  139.         C *c25 = pc;   
  140.   
  141.         C *c26 = pc;   
  142.         C *c27 = pc;   
  143.         C *c28 = pc;   
  144.         C *c29 = pc;   
  145.         C *c30 = pc;   
  146.   
  147.         C *c31 = pc;   
  148.         C *c32 = pc;   
  149.         C *c33 = pc;   
  150.         C *c34 = pc;   
  151.         C *c35 = pc;   
  152.   
  153.         C *c36 = pc;   
  154.         C *c37 = pc;   
  155.         C *c38 = pc;   
  156.         C *c39 = pc;   
  157.         C *c40 = pc;   
  158.   
  159. #elif TM == 3   
  160.         C *c1 = (C *)pthread_getspecific(pc);   
  161.         C *c2 = (C *)pthread_getspecific(pc);   
  162.         C *c3 = (C *)pthread_getspecific(pc);   
  163.         C *c4 = (C *)pthread_getspecific(pc);   
  164.         C *c5 = (C *)pthread_getspecific(pc);   
  165.   
  166.         C *c6 = (C *)pthread_getspecific(pc);   
  167.         C *c7 = (C *)pthread_getspecific(pc);   
  168.         C *c8 = (C *)pthread_getspecific(pc);   
  169.         C *c9 = (C *)pthread_getspecific(pc);   
  170.         C *c10 = (C *)pthread_getspecific(pc);   
  171.   
  172.         C *c11 = (C *)pthread_getspecific(pc);   
  173.         C *c12 = (C *)pthread_getspecific(pc);   
  174.         C *c13 = (C *)pthread_getspecific(pc);   
  175.         C *c14 = (C *)pthread_getspecific(pc);   
  176.         C *c15 = (C *)pthread_getspecific(pc);   
  177.   
  178.         C *c16 = (C *)pthread_getspecific(pc);   
  179.         C *c17 = (C *)pthread_getspecific(pc);   
  180.         C *c18 = (C *)pthread_getspecific(pc);   
  181.         C *c19 = (C *)pthread_getspecific(pc);   
  182.         C *c20 = (C *)pthread_getspecific(pc);   
  183.   
  184.         C *c21 = (C *)pthread_getspecific(pc);   
  185.         C *c22 = (C *)pthread_getspecific(pc);   
  186.         C *c23 = (C *)pthread_getspecific(pc);   
  187.         C *c24 = (C *)pthread_getspecific(pc);   
  188.         C *c25 = (C *)pthread_getspecific(pc);   
  189.   
  190.         C *c26 = (C *)pthread_getspecific(pc);   
  191.         C *c27 = (C *)pthread_getspecific(pc);   
  192.         C *c28 = (C *)pthread_getspecific(pc);   
  193.         C *c29 = (C *)pthread_getspecific(pc);   
  194.         C *c30 = (C *)pthread_getspecific(pc);   
  195.   
  196.         C *c31 = (C *)pthread_getspecific(pc);   
  197.         C *c32 = (C *)pthread_getspecific(pc);   
  198.         C *c33 = (C *)pthread_getspecific(pc);   
  199.         C *c34 = (C *)pthread_getspecific(pc);   
  200.         C *c35 = (C *)pthread_getspecific(pc);   
  201.   
  202.         C *c36 = (C *)pthread_getspecific(pc);   
  203.         C *c37 = (C *)pthread_getspecific(pc);   
  204.         C *c38 = (C *)pthread_getspecific(pc);   
  205.         C *c39 = (C *)pthread_getspecific(pc);   
  206.         C *c40 = (C *)pthread_getspecific(pc);   
  207.   
  208. #else   
  209.         C *c1 = pc;   
  210.         C *c2 = pc;   
  211.         C *c3 = pc;   
  212.         C *c4 = pc;   
  213.         C *c5 = pc;   
  214.   
  215.         C *c6 = pc;   
  216.         C *c7 = pc;   
  217.         C *c8 = pc;   
  218.         C *c9 = pc;   
  219.         C *c10 = pc;   
  220.   
  221.         C *c11 = pc;   
  222.         C *c12 = pc;   
  223.         C *c13 = pc;   
  224.         C *c14 = pc;   
  225.         C *c15 = pc;   
  226.   
  227.         C *c16 = pc;   
  228.         C *c17 = pc;   
  229.         C *c18 = pc;   
  230.         C *c19 = pc;   
  231.         C *c20 = pc;   
  232.   
  233.         C *c21 = pc;   
  234.         C *c22 = pc;   
  235.         C *c23 = pc;   
  236.         C *c24 = pc;   
  237.         C *c25 = pc;   
  238.   
  239.         C *c26 = pc;   
  240.         C *c27 = pc;   
  241.         C *c28 = pc;   
  242.         C *c29 = pc;   
  243.         C *c30 = pc;   
  244.   
  245.         C *c31 = pc;   
  246.         C *c32 = pc;   
  247.         C *c33 = pc;   
  248.         C *c34 = pc;   
  249.         C *c35 = pc;   
  250.   
  251.         C *c36 = pc;   
  252.         C *c37 = pc;   
  253.         C *c38 = pc;   
  254.         C *c39 = pc;   
  255.         C *c40 = pc;   
  256.   
  257. #endif   
  258.     }   
  259.     gettimeofday(&tm_end, NULL);   
  260.     switches *= 40;   
  261.     long long ns = (tm_end.tv_sec - tm_start.tv_sec) * 1000LL * 1000LL * 1000LL +   
  262.         (tm_end.tv_usec - tm_start.tv_usec) * 1000LL;   
  263.     std::cout << "####Benchmark result#### " << testType << std::endl;   
  264.     std::cout << "Totol switches : " << switches << std::endl;   
  265.     std::cout << "Cost per switch(ns) : " << (double)ns/switches << std::endl;   
  266.     std::cout << "All cost switch(ns) : " << ns << std::endl;   
  267.     std::cout << "####Benchmark result####" << std::endl;   
  268. }   
  269.   
  270. int main() {   
  271.     boost::thread bt(&boostthreadFunc);   
  272.     bt.join();   
  273.     printf("main exit.. ");   
  274.     return 0;   
  275. }   

 详情请访问libgod官网..

原文地址:https://www.cnblogs.com/libgod/p/3444986.html