]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.1/test/src/benchmark_queue.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.1 / test / src / benchmark_queue.c
1 #include "internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 void benchmark_lfds611_queue( void )\r
9 {\r
10   unsigned int\r
11     loop,\r
12     thread_count,\r
13     cpu_count;\r
14 \r
15   struct lfds611_queue_state\r
16     *qs;\r
17 \r
18   struct lfds611_queue_benchmark\r
19     *qb;\r
20 \r
21   thread_state_t\r
22     *thread_handles;\r
23 \r
24   lfds611_atom_t\r
25     total_operations_for_full_test_for_all_cpus,\r
26     total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;\r
27 \r
28   double\r
29     mean_operations_per_second_per_cpu,\r
30     difference_per_second_per_cpu,\r
31     total_difference_per_second_per_cpu,\r
32     std_dev_per_second_per_cpu,\r
33     scalability;\r
34 \r
35   /* TRD : here we benchmark the queue\r
36 \r
37            the benchmark is to have a single queue\r
38            where a worker thread busy-works dequeuing and then queuing\r
39   */\r
40 \r
41   cpu_count = abstraction_cpu_count();\r
42 \r
43   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count );\r
44 \r
45   qb = (struct lfds611_queue_benchmark *) malloc( sizeof(struct lfds611_queue_benchmark) * cpu_count );\r
46 \r
47   // TRD : print the benchmark ID and CSV header\r
48   printf( "\n"\r
49           "Release %s Queue Benchmark #1\n"\r
50           "CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );\r
51 \r
52   // TRD : we run CPU count times for scalability\r
53   for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )\r
54   {\r
55     // TRD : initialisation\r
56     lfds611_queue_new( &qs, 1000 );\r
57 \r
58     for( loop = 0 ; loop < cpu_count ; loop++ )\r
59     {\r
60       (qb+loop)->qs = qs;\r
61       (qb+loop)->operation_count = 0;\r
62     }\r
63 \r
64     // TRD : populate the queue (we don't actually use the user data)\r
65     for( loop = 0 ; loop < 500 ; loop++ )\r
66       lfds611_queue_enqueue( qs, (void *) (lfds611_atom_t) loop );\r
67 \r
68     // TRD : main test\r
69     for( loop = 0 ; loop < thread_count ; loop++ )\r
70       abstraction_thread_start( &thread_handles[loop], loop, benchmark_lfds611_queue_thread_delfds611_queue_and_enqueue, qb+loop );\r
71 \r
72     for( loop = 0 ; loop < thread_count ; loop++ )\r
73       abstraction_thread_wait( thread_handles[loop] );\r
74 \r
75     // TRD : post test math\r
76     total_operations_for_full_test_for_all_cpus = 0;\r
77     total_difference_per_second_per_cpu = 0;\r
78 \r
79     for( loop = 0 ; loop < thread_count ; loop++ )\r
80       total_operations_for_full_test_for_all_cpus += (qb+loop)->operation_count;\r
81 \r
82     mean_operations_per_second_per_cpu = ((double) total_operations_for_full_test_for_all_cpus / (double) thread_count) / (double) 10;\r
83 \r
84     if( thread_count == 1 )\r
85       total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;\r
86 \r
87     for( loop = 0 ; loop < thread_count ; loop++ )\r
88     {\r
89       difference_per_second_per_cpu = ((double) (qb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;\r
90       total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;\r
91     }\r
92 \r
93     std_dev_per_second_per_cpu = sqrt( (double) total_difference_per_second_per_cpu );\r
94 \r
95     scalability = (double) total_operations_for_full_test_for_all_cpus / (double) (total_operations_for_full_test_for_all_cpus_for_one_cpu * thread_count);\r
96 \r
97     printf( "%u,%u,%.0f,%.0f,%0.2f\n", thread_count, (unsigned int) total_operations_for_full_test_for_all_cpus, mean_operations_per_second_per_cpu, std_dev_per_second_per_cpu, scalability );\r
98 \r
99     // TRD : cleanup\r
100     lfds611_queue_delete( qs, NULL, NULL );\r
101   }\r
102 \r
103   free( qb );\r
104 \r
105   free( thread_handles );\r
106 \r
107   return;\r
108 }\r
109 \r
110 \r
111 \r
112 \r
113 \r
114 /****************************************************************************/\r
115 thread_return_t CALLING_CONVENTION benchmark_lfds611_queue_thread_delfds611_queue_and_enqueue( void *queue_benchmark )\r
116 {\r
117   struct lfds611_queue_benchmark\r
118     *qb;\r
119 \r
120   void\r
121     *user_data;\r
122 \r
123   time_t\r
124     start_time;\r
125 \r
126   assert( queue_benchmark != NULL );\r
127 \r
128   qb = (struct lfds611_queue_benchmark *) queue_benchmark;\r
129 \r
130   time( &start_time );\r
131 \r
132   while( time(NULL) < start_time + 10 )\r
133   {\r
134     lfds611_queue_dequeue( qb->qs, &user_data );\r
135     lfds611_queue_enqueue( qb->qs, user_data );\r
136 \r
137     qb->operation_count += 2;\r
138   }\r
139 \r
140   return( (thread_return_t) EXIT_SUCCESS );\r
141 }\r
142 \r