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