1 #include "internal.h"
\r
7 /****************************************************************************/
\r
8 void benchmark_lfds611_freelist( void )
\r
15 struct lfds611_freelist_state
\r
18 struct lfds611_freelist_benchmark
\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
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
35 /* TRD : here we benchmark the freelist
\r
37 the benchmark is to have a single freelist
\r
38 where a worker thread busy-works popping and then pushing
\r
41 cpu_count = abstraction_cpu_count();
\r
43 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count );
\r
45 fb = (struct lfds611_freelist_benchmark *) malloc( sizeof(struct lfds611_freelist_benchmark) * cpu_count );
\r
47 // TRD : print the benchmark ID and CSV header
\r
49 "Release %s Freelist Benchmark #1\n"
\r
50 "CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );
\r
52 // TRD : we run CPU count times for scalability
\r
53 for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
\r
55 // TRD : initialisation
\r
56 lfds611_freelist_new( &fs, 1000, NULL, NULL );
\r
58 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
61 (fb+loop)->operation_count = 0;
\r
65 for( loop = 0 ; loop < thread_count ; loop++ )
\r
66 abstraction_thread_start( &thread_handles[loop], loop, benchmark_lfds611_freelist_thread_pop_and_push, fb+loop );
\r
68 for( loop = 0 ; loop < thread_count ; loop++ )
\r
69 abstraction_thread_wait( thread_handles[loop] );
\r
71 // TRD : post test math
\r
72 total_operations_for_full_test_for_all_cpus = 0;
\r
73 total_difference_per_second_per_cpu = 0;
\r
75 for( loop = 0 ; loop < thread_count ; loop++ )
\r
76 total_operations_for_full_test_for_all_cpus += (fb+loop)->operation_count;
\r
78 mean_operations_per_second_per_cpu = ((double) total_operations_for_full_test_for_all_cpus / (double) thread_count) / (double) 10;
\r
80 if( thread_count == 1 )
\r
81 total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
\r
83 for( loop = 0 ; loop < thread_count ; loop++ )
\r
85 difference_per_second_per_cpu = ((double) (fb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
\r
86 total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
\r
89 std_dev_per_second_per_cpu = sqrt( (double) total_difference_per_second_per_cpu );
\r
91 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
93 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
96 lfds611_freelist_delete( fs, NULL, NULL );
\r
101 free( thread_handles );
\r
110 /****************************************************************************/
\r
111 thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_push( void *freelist_benchmark )
\r
113 struct lfds611_freelist_benchmark
\r
116 struct lfds611_freelist_element
\r
122 assert( freelist_benchmark != NULL );
\r
124 fb = (struct lfds611_freelist_benchmark *) freelist_benchmark;
\r
126 time( &start_time );
\r
128 while( time(NULL) < start_time + 10 )
\r
130 lfds611_freelist_pop( fb->fs, &fe );
\r
131 lfds611_freelist_push( fb->fs, fe );
\r
133 fb->operation_count += 2;
\r
136 return( (thread_return_t) EXIT_SUCCESS );
\r