win-pvdrivers

view liblfds.6/test/src/benchmark_queue.c @ 766:6300617040e0

Big changes - not ready for production use.
Removed all the custom DMA handling code as it was completely incompatible with the Windows verifier.
Added liblfds (using the lock free stack) from liblfds.org so that grant's can be obtained at DIRQL.
Fixed xennet and xenvbd to support the changes.
xenusb and xenscsi almost certainly will not yet work after the changes.
author James Harper <james.harper@bendigoit.com.au>
date Sun Jan 31 21:28:42 2010 +1100 (2010-01-31)
parents
children
line source
1 #include "internal.h"
7 /****************************************************************************/
8 void benchmark_queue( void )
9 {
10 unsigned int
11 loop,
12 thread_count,
13 cpu_count;
15 struct queue_state
16 *qs;
18 struct queue_benchmark
19 *qb;
21 thread_state_t
22 *thread_handles;
24 atom_t
25 total_operations_for_full_test_for_all_cpus,
26 total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
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;
35 /* TRD : here we benchmark the queue
37 the benchmark is to have a single queue
38 where a worker thread busy-works dequeuing and then queuing
39 */
41 cpu_count = abstraction_cpu_count();
43 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count );
45 qb = (struct queue_benchmark *) malloc( sizeof(struct queue_benchmark) * cpu_count );
47 // TRD : print the benchmark ID and CSV header
48 printf( "\n"
49 "Release %d Queue Benchmark #1\n"
50 "CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LIBLFDS_RELEASE_NUMBER );
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 queue_new( &qs, 1000 );
58 for( loop = 0 ; loop < cpu_count ; loop++ )
59 {
60 (qb+loop)->qs = qs;
61 (qb+loop)->operation_count = 0;
62 }
64 // TRD : populate the queue (we don't actually use the user data)
65 for( loop = 0 ; loop < 500 ; loop++ )
66 queue_enqueue( qs, (void *) (atom_t) loop );
68 // TRD : main test
69 for( loop = 0 ; loop < thread_count ; loop++ )
70 abstraction_thread_start( &thread_handles[loop], loop, benchmark_queue_thread_dequeue_and_enqueue, qb+loop );
72 for( loop = 0 ; loop < thread_count ; loop++ )
73 abstraction_thread_wait( thread_handles[loop] );
75 // TRD : post test math
76 total_operations_for_full_test_for_all_cpus = 0;
77 total_difference_per_second_per_cpu = 0;
79 for( loop = 0 ; loop < thread_count ; loop++ )
80 total_operations_for_full_test_for_all_cpus += (qb+loop)->operation_count;
82 mean_operations_per_second_per_cpu = ((double) total_operations_for_full_test_for_all_cpus / (double) thread_count) / (double) 10;
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;
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 }
93 std_dev_per_second_per_cpu = sqrt( (double) total_difference_per_second_per_cpu );
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);
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 );
99 // TRD : cleanup
100 queue_delete( qs, NULL, NULL );
101 }
103 free( qb );
105 free( thread_handles );
107 return;
108 }
114 /****************************************************************************/
115 thread_return_t CALLING_CONVENTION benchmark_queue_thread_dequeue_and_enqueue( void *queue_benchmark )
116 {
117 struct queue_benchmark
118 *qb;
120 void
121 *user_data;
123 time_t
124 start_time;
126 assert( queue_benchmark != NULL );
128 qb = (struct queue_benchmark *) queue_benchmark;
130 time( &start_time );
132 while( time(NULL) < start_time + 10 )
133 {
134 queue_dequeue( qb->qs, &user_data );
135 queue_enqueue( qb->qs, user_data );
137 qb->operation_count += 2;
138 }
140 return( (thread_return_t) EXIT_SUCCESS );
141 }