#include "rq_bench.hfa" thread Partner { Partner * partner; unsigned long long count; }; void ?{}( Partner & this ) { ((thread&)this){ bench_cluster }; } void main( Partner & this ) { this.count = 0; for() { park(); unpark( *this.partner ); this.count ++; if( clock_mode && stop) break; if(!clock_mode && this.count >= stop_count) break; } __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST); } int main(int argc, char * argv[]) { unsigned ring_size = 2; cfa_option opt[] = { BENCH_OPT, { 'r', "ringsize", "Number of threads in a cycle", ring_size } }; BENCH_OPT_PARSE("cforall cycle benchmark"); { unsigned long long global_counter = 0; unsigned tthreads = nthreads * ring_size; Time start, end; BenchCluster bc = { nprocs }; { threads_left = tthreads; Partner threads[tthreads]; for(i; tthreads) { unsigned pi = (i + nthreads) % tthreads; threads[i].partner = &threads[pi]; } printf("Starting\n"); bool is_tty = isatty(STDOUT_FILENO); start = getTimeNsec(); for(i; nthreads) { unpark( threads[i] ); } wait(start, is_tty); stop = true; end = getTimeNsec(); printf("\nDone\n"); for(i; tthreads) { global_counter += join( threads[i] ).count; } } printf("Took %'ld ms\n", (end - start)`ms); printf("Yields per second : %'18.2lf\n", ((double)global_counter) / (end - start)`s); printf("ns per yields : %'18.2lf\n", ((double)(end - start)`ns) / global_counter); printf("Total yields : %'15llu\n", global_counter); printf("Yields per threads : %'15llu\n", global_counter / tthreads); printf("Yields per procs : %'15llu\n", global_counter / nprocs); printf("Yields/sec/procs : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s); printf("ns per yields/procs : %'18.2lf\n", ((double)(end - start)`ns) / (global_counter / nprocs)); fflush(stdout); } return 0; }