Advertisement
Guest User

a,c

a guest
Dec 12th, 2014
920
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.43 KB | None | 0 0
  1. #define _GNU_SOURCE
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <pthread.h>
  7. #include <sched.h>
  8.  
  9. #include "q3.h"
  10. //#include "q.h"
  11. //#include "qlock.h"
  12.  
  13. static struct msg *msgs;
  14.  
  15.  
  16. #define POP_CNT         7
  17. #define PUSH_CNT        7
  18.  
  19. #define MSG_CNT         (PUSH_CNT * 1000000)
  20.  
  21. static inline uint64_t
  22. rdtsc(void)
  23. {
  24.     union {
  25.         uint64_t tsc_64;
  26.         struct {
  27.             uint32_t lo_32;
  28.             uint32_t hi_32;
  29.         };
  30.     } tsc;
  31.  
  32.     asm volatile("rdtsc" :
  33.         "=a" (tsc.lo_32),
  34.         "=d" (tsc.hi_32));
  35.     return tsc.tsc_64;
  36. }
  37.  
  38. static volatile int quit = 0;
  39. static volatile int pop_total = 0;
  40. static volatile int push_total = 0;
  41.  
  42. static volatile uint64_t push_cycles = 0;
  43. static volatile uint64_t pop_cycles = 0;
  44.  
  45.  
  46. static void *
  47. pop_task(void *arg)
  48. {
  49.         struct queue *q = arg;
  50.         uint64_t start = rdtsc();
  51.         int cnt = 0;
  52.  
  53.         while (!quit)
  54.                 cnt += !!pop(q);
  55.  
  56.         pop_cycles += rdtsc() - start;
  57.         pop_total += cnt;
  58.  
  59.         return NULL;
  60. }
  61.  
  62. static void *
  63. push_task(void *arg)
  64. {
  65.         struct queue *q = arg;
  66.         uint64_t start = rdtsc();
  67.         int i;
  68.  
  69.         for (i = 0; i < MSG_CNT / PUSH_CNT; i++)
  70.                 while (push(q, msgs + i) == -1);
  71.  
  72.         push_cycles += rdtsc() - start;
  73.         push_total += MSG_CNT / PUSH_CNT;
  74.         if (push_total == MSG_CNT)
  75.                 quit = 1;
  76.  
  77.         return NULL;
  78. }
  79.  
  80. /* topology for Xeon E5-2670 Sandybridge */
  81. static const int socket_top[] = {
  82.     1,  2,  3,  4,  5,  6,  7,
  83.     16, 17, 18, 19, 20, 21, 22, 23,
  84.     8,  9,  10, 11, 12, 13, 14, 15,
  85.     24, 25, 26, 27, 28, 29, 30, 31
  86. };
  87.  
  88. #define CORE_ID(i)      socket_top[(i)]
  89.  
  90.  
  91. static int
  92. start_thread(int id,
  93.              void *(*cb)(void *),
  94.              void *arg,
  95.              pthread_t *tid)
  96. {
  97.         pthread_t kid;
  98.         pthread_attr_t attr;
  99.         cpu_set_t cpuset;
  100.         int core_id;
  101.  
  102.         if (id < 0 || id >= sizeof(socket_top) / sizeof(int))
  103.                 return -1;
  104.  
  105.         if (pthread_attr_init(&attr))
  106.                 return -1;
  107.  
  108.         CPU_ZERO(&cpuset);
  109.         core_id = CORE_ID(id);
  110.         CPU_SET(core_id, &cpuset);
  111.  
  112.         if (pthread_create(&kid, &attr, cb, arg))
  113.                 return -1;
  114.         if (pthread_setaffinity_np(kid, sizeof(cpu_set_t), &cpuset))
  115.                 return -1;
  116.  
  117.         if (tid)
  118.                 *tid = kid;
  119.  
  120.         return 0;
  121. }
  122.  
  123. static int
  124. setaffinity(int core_id)
  125. {
  126.         cpu_set_t cpuset;
  127.         pthread_t me = pthread_self();
  128.  
  129.         CPU_ZERO(&cpuset);
  130.         CPU_SET(core_id, &cpuset);
  131.  
  132.         if (pthread_setaffinity_np(me, sizeof(cpu_set_t), &cpuset))
  133.                 return -1;
  134.  
  135.         return 0;
  136. }
  137.  
  138. int
  139. main(void)
  140. {
  141.         struct queue *q = qinit();
  142.         int i;
  143.         pthread_t kids[POP_CNT + PUSH_CNT];
  144.  
  145.         setaffinity(0);
  146.  
  147.         msgs = calloc(MSG_CNT, sizeof(struct msg));
  148.         for (i = 0; i < POP_CNT; i++)
  149.                 start_thread(i, pop_task, q, &kids[i]);
  150.         for (; i < POP_CNT + PUSH_CNT; i++)
  151.                 start_thread(i, push_task, q, &kids[i]);
  152.         for (i = 0; i < POP_CNT + PUSH_CNT; i++)
  153.                 pthread_join(kids[i], NULL);
  154.  
  155.         printf("pop total: %d\n", pop_total);
  156.         printf("pop cycles/msg: %lu\n", pop_cycles / pop_total);
  157.         printf("push cycles/msg: %lu\n", push_cycles / MSG_CNT);
  158.  
  159.         return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement