7 /****************************************************************************/
8 void benchmark_lfds601_ringbuffer( void )
15 struct lfds601_ringbuffer_state
18 struct lfds601_ringbuffer_benchmark
25 total_operations_for_full_test_for_all_cpus,
26 total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
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,
35 /* TRD : here we benchmark the ringbuffer
37 the benchmark is to have a single ringbuffer
38 where a worker thread busy-works writing and then reading
41 cpu_count = abstraction_cpu_count();
43 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count );
45 rb = (struct lfds601_ringbuffer_benchmark *) malloc( sizeof(struct lfds601_ringbuffer_benchmark) * cpu_count );
47 // TRD : print the benchmark ID and CSV header
49 "Release %s Ringbuffer Benchmark #1\n"
50 "CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS601_RELEASE_NUMBER_STRING );
52 // TRD : we run CPU count times for scalability
53 for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
55 // TRD : initialisation
56 lfds601_ringbuffer_new( &rs, 1000, NULL, NULL );
58 for( loop = 0 ; loop < cpu_count ; loop++ )
61 (rb+loop)->operation_count = 0;
65 for( loop = 0 ; loop < thread_count ; loop++ )
66 abstraction_thread_start( &thread_handles[loop], loop, benchmark_lfds601_ringbuffer_thread_write_and_read, rb+loop );
68 for( loop = 0 ; loop < thread_count ; loop++ )
69 abstraction_thread_wait( thread_handles[loop] );
71 // TRD : post test math
72 total_operations_for_full_test_for_all_cpus = 0;
73 total_difference_per_second_per_cpu = 0;
75 for( loop = 0 ; loop < thread_count ; loop++ )
76 total_operations_for_full_test_for_all_cpus += (rb+loop)->operation_count;
78 mean_operations_per_second_per_cpu = ((double) total_operations_for_full_test_for_all_cpus / (double) thread_count) / (double) 10;
80 if( thread_count == 1 )
81 total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
83 for( loop = 0 ; loop < thread_count ; loop++ )
85 difference_per_second_per_cpu = ((double) (rb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
86 total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
89 std_dev_per_second_per_cpu = sqrt( (double) total_difference_per_second_per_cpu );
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);
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 );
96 lfds601_ringbuffer_delete( rs, NULL, NULL );
101 free( thread_handles );
110 /****************************************************************************/
111 thread_return_t CALLING_CONVENTION benchmark_lfds601_ringbuffer_thread_write_and_read( void *lfds601_ringbuffer_benchmark )
113 struct lfds601_ringbuffer_benchmark
116 struct lfds601_freelist_element
122 assert( lfds601_ringbuffer_benchmark != NULL );
124 rb = (struct lfds601_ringbuffer_benchmark *) lfds601_ringbuffer_benchmark;
128 while( time(NULL) < start_time + 10 )
130 lfds601_ringbuffer_get_write_element( rb->rs, &fe, NULL );
131 lfds601_ringbuffer_put_write_element( rb->rs, fe );
133 lfds601_ringbuffer_get_read_element( rb->rs, &fe );
134 lfds601_ringbuffer_put_read_element( rb->rs, fe );
136 rb->operation_count += 2;
139 return( (thread_return_t) EXIT_SUCCESS );