Changeset 74ec742 for benchmark/readyQ


Ignore:
Timestamp:
May 20, 2022, 10:36:45 AM (4 years ago)
Author:
m3zulfiq <m3zulfiq@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
25fa20a
Parents:
29d8c02 (diff), 7831e8fb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
benchmark/readyQ
Files:
3 added
11 edited

Legend:

Unmodified
Added
Removed
  • benchmark/readyQ/bench.go

    r29d8c02 r74ec742  
    7171                duration = 5
    7272                clock_mode = true
    73                 fmt.Printf("Running for %f seconds\n", duration)
     73                fmt.Printf("Running for %f seconds (default)\n", duration)
    7474        }
    7575
  • benchmark/readyQ/churn.cfa

    r29d8c02 r74ec742  
    11#include "rq_bench.hfa"
    22
     3#include <locks.hfa>
     4
    35unsigned spot_cnt = 2;
    4 bench_sem * volatile * spots;
     6semaphore * spots;
    57
    68thread BThrd {
    79        unsigned long long count;
    810        unsigned long long blocks;
    9         bench_sem sem;
     11        bool skip;
    1012};
    1113
     
    1416        this.count  = 0;
    1517        this.blocks = 0;
     18        this.skip = false;
    1619}
    1720
     
    1922
    2023void main( BThrd & this ) with( this ) {
    21         wait( sem );
     24        park();
    2225        for() {
    23                 uint32_t r = prng();
    24                 bench_sem * next = __atomic_exchange_n(&spots[r % spot_cnt], &sem, __ATOMIC_SEQ_CST);
    25                 if(next) post( *next );
    26                 blocks += wait( sem );
     26                uint32_t r = prng(this);
     27                semaphore & sem = spots[r % spot_cnt];
     28                if(!skip) V( sem );
     29                blocks += P( sem );
     30                skip = false;
     31
    2732                count ++;
    2833                if( clock_mode && stop) break;
     
    3944                { 's', "spots", "Number of spots in the system", spot_cnt }
    4045        };
    41         BENCH_OPT_PARSE("cforall cycle benchmark");
     46        BENCH_OPT_PARSE("cforall churn benchmark");
    4247
    4348        {
     
    4954                        spots = aalloc(spot_cnt);
    5055                        for(i; spot_cnt) {
    51                                 spots[i] = 0p;
     56                                (spots[i]){ 0 };
    5257                        }
    5358
     
    5560                        BThrd * threads[nthreads];
    5661                        for(i; nthreads ) {
    57                                 threads[i] = malloc();
    58                                 (*threads[i]){};
     62                                BThrd & t = *(threads[i] = malloc());
     63                                (t){};
     64                                t.skip = i < spot_cnt;
    5965                        }
    6066                        printf("Starting\n");
     
    6470
    6571                        for(i; nthreads) {
    66                                 post( threads[i]->sem );
     72                                unpark( *threads[i] );
    6773                        }
    6874                        wait(start, is_tty);
     
    7278                        printf("\nDone\n");
    7379
     80                        for(i; spot_cnt) {
     81                                for(10000) V( spots[i] );
     82                        }
     83
    7484                        for(i; nthreads) {
    75                                 post( threads[i]->sem );
    7685                                BThrd & thrd = join( *threads[i] );
    7786                                global_counter += thrd.count;
  • benchmark/readyQ/cycle.cpp

    r29d8c02 r74ec742  
    4646                        }
    4747                        for(unsigned i = 0; i < tthreads; i++) {
    48                                 threads[i] = new Fibre( reinterpret_cast<void (*)(void *)>(partner_main), &thddata[i] );
     48                                threads[i] = new Fibre();
     49                                threads[i]->run( partner_main, &thddata[i] );
    4950                        }
    5051                        printf("Starting\n");
  • benchmark/readyQ/rq_bench.hpp

    r29d8c02 r74ec742  
    143143        }
    144144
     145        if(strcmp(arg, "Y") == 0) {
     146                value = true;
     147                return true;
     148        }
     149
     150        if(strcmp(arg, "y") == 0) {
     151                value = true;
     152                return true;
     153        }
     154
    145155        if(strcmp(arg, "no") == 0) {
     156                value = false;
     157                return true;
     158        }
     159
     160        if(strcmp(arg, "N") == 0) {
     161                value = false;
     162                return true;
     163        }
     164
     165        if(strcmp(arg, "n") == 0) {
    146166                value = false;
    147167                return true;
  • benchmark/readyQ/transfer.cfa

    r29d8c02 r74ec742  
    1414
    1515bool exhaust = false;
     16volatile bool estop = false;
     17
    1618
    1719thread$ * the_main;
     
    3537static void waitgroup() {
    3638        Time start = timeHiRes();
    37         for(i; nthreads) {
     39        OUTER: for(i; nthreads) {
    3840                PRINT( sout | "Waiting for :" | i | "(" | threads[i]->idx | ")"; )
    3941                while( threads[i]->idx != lead_idx ) {
     
    4244                                print_stats_now( bench_cluster, CFA_STATS_READY_Q | CFA_STATS_IO );
    4345                                serr | "Programs has been blocked for more than 5 secs";
    44                                 exit(1);
     46                                estop = true;
     47                                unpark( the_main );
     48                                break OUTER;
    4549                        }
    4650                }
     
    5963static void lead(MyThread & this) {
    6064        this.idx = ++lead_idx;
    61         if(lead_idx > stop_count) {
     65        if(lead_idx > stop_count || estop) {
    6266                PRINT( sout | "Leader" | this.id | "done"; )
    6367                unpark( the_main );
     
    100104                        wait( this );
    101105                }
    102                 if(lead_idx > stop_count) break;
     106                if(lead_idx > stop_count || estop) break;
    103107        }
    104108}
     
    172176        sout | "Number of processors    : " | nprocs;
    173177        sout | "Number of threads       : " | nthreads;
    174         sout | "Total Operations(ops)   : " | stop_count;
     178        sout | "Total Operations(ops)   : " | lead_idx - 1;
    175179        sout | "Threads parking on wait : " | (exhaust ? "yes" : "no");
    176180        sout | "Rechecking              : " | rechecks;
     181        sout | "ns per transfer         : " | (end - start)`dms / lead_idx;
    177182
    178183
  • benchmark/readyQ/transfer.cpp

    r29d8c02 r74ec742  
    1212
    1313bool exhaust = false;
     14volatile bool estop = false;
    1415
    1516bench_sem the_main;
     
    4243                                if( to_miliseconds(timeHiRes() - start) > 5'000 ) {
    4344                                        std::cerr << "Programs has been blocked for more than 5 secs" << std::endl;
    44                                         std::exit(1);
     45                                        estop = true;
     46                                        the_main.post();
     47                                        goto END;
    4548                                }
    4649                        }
    4750                }
     51                END:;
    4852                PRINT( std::cout | "Waiting done"; )
    4953        }
     
    5963        void lead() {
    6064                this->idx = ++lead_idx;
    61                 if(lead_idx > stop_count) {
     65                if(lead_idx > stop_count || estop) {
    6266                        PRINT( std::cout << "Leader " << this->id << " done" << std::endl; )
    6367                        the_main.post();
     
    8892        }
    8993
    90         static void main(void * arg) {
    91                 MyThread & self = *reinterpret_cast<MyThread*>(arg);
     94        static void main(MyThread * arg) {
     95                MyThread & self = *arg;
    9296                self.park();
    9397
     
    101105                                self.wait();
    102106                        }
    103                         if(lead_idx > stop_count) break;
     107                        if(lead_idx > stop_count || estop) break;
    104108                }
    105109        }
     
    144148                        for(size_t i = 0; i < nthreads; i++) {
    145149                                threads[i] = new MyThread( i );
    146                                 handles[i] = new Fibre( MyThread::main, threads[i] );
     150                                handles[i] = new Fibre();
     151                                handles[i]->run( MyThread::main, threads[i] );
    147152                        }
    148153
     
    164169                                PRINT( std::cout << i << " joined" << std::endl; )
    165170                                rechecks += thrd.rechecks;
    166                                 // delete( handles[i] );
    167171                                delete( threads[i] );
    168172                        }
     
    176180        std::cout << "Number of processors    : " << nprocs << std::endl;
    177181        std::cout << "Number of threads       : " << nthreads << std::endl;
    178         std::cout << "Total Operations(ops)   : " << stop_count << std::endl;
     182        std::cout << "Total Operations(ops)   : " << (lead_idx - 1) << std::endl;
    179183        std::cout << "Threads parking on wait : " << (exhaust ? "yes" : "no") << std::endl;
    180184        std::cout << "Rechecking              : " << rechecks << std::endl;
     185        std::cout << "ns per transfer         : " << std::fixed << (((double)(end - start)) / (lead_idx)) << std::endl;
    181186
    182187
  • benchmark/readyQ/transfer.go

    r29d8c02 r74ec742  
    66        "math/rand"
    77        "os"
     8        "regexp"
    89        "runtime"
    910        "sync/atomic"
     
    1617        id uint64
    1718        idx uint64
     19        estop uint64
    1820        seed uint64
    1921}
     
    3436
    3537func NewLeader(size uint64) (*LeaderInfo) {
    36         this := &LeaderInfo{0, 0, uint64(os.Getpid())}
     38        this := &LeaderInfo{0, 0, 0, uint64(os.Getpid())}
    3739
    3840        r := rand.Intn(10)
     
    5153}
    5254
    53 func waitgroup(idx uint64, threads [] MyThread) {
     55func waitgroup(leader * LeaderInfo, idx uint64, threads [] MyThread, main_sem chan struct {}) {
    5456        start := time.Now()
     57        Outer:
    5558        for i := 0; i < len(threads); i++ {
    5659                // fmt.Fprintf(os.Stderr, "Waiting for :%d (%d)\n", threads[i].id, atomic.LoadUint64(&threads[i].idx) );
     
    6164                        if delta.Seconds() > 5 {
    6265                                fmt.Fprintf(os.Stderr, "Programs has been blocked for more than 5 secs")
    63                                 os.Exit(1)
     66                                atomic.StoreUint64(&leader.estop, 1);
     67                                main_sem <- (struct {}{})
     68                                break Outer
    6469                        }
    6570                }
     
    7479                if i != me {
    7580                        // debug!( "Leader waking {}", i);
     81                        defer func() {
     82                                if err := recover(); err != nil {
     83                                        fmt.Fprintf(os.Stderr, "Panic occurred: %s\n", err)
     84                                }
     85                        }()
    7686                        threads[i].sem <- (struct {}{})
    7787                }
     
    8494        atomic.StoreUint64(&leader.idx, nidx);
    8595
    86         if nidx > stop_count {
     96        if nidx > stop_count || atomic.LoadUint64(&leader.estop) != 0 {
    8797                // debug!( "Leader {} done", this.id);
    8898                main_sem <- (struct {}{})
     
    92102        // debug!( "====================\nLeader no {} : {}", nidx, this.id);
    93103
    94         waitgroup(nidx, threads);
     104        waitgroup(leader, nidx, threads, main_sem);
    95105
    96106        leader.next( uint64(len(threads)) );
     
    146156                        waitleader( exhaust, leader, &threads[me], &r )
    147157                }
    148                 if atomic.LoadUint64(&leader.idx) > stop_count { break; }
     158                if atomic.LoadUint64(&leader.idx) > stop_count || atomic.LoadUint64(&leader.estop) != 0 { break; }
    149159        }
    150160
     
    155165func main() {
    156166        // Benchmark specific command line arguments
    157         exhaustOpt := flag.Bool("e", false, "Whether or not threads that have seen the new epoch should park instead of yielding.")
     167        exhaustOpt := flag.String("e", "no", "Whether or not threads that have seen the new epoch should park instead of yielding.")
    158168
    159169        // General benchmark initialization and deinitialization
    160         defer bench_init()()
    161 
    162         exhaust := *exhaustOpt;
     170        bench_init()
     171
     172        exhaustVal := *exhaustOpt;
     173
     174        var exhaust bool
     175        re_yes := regexp.MustCompile("[Yy]|[Yy][Ee][Ss]")
     176        re_no  := regexp.MustCompile("[Nn]|[Nn][Oo]")
     177        if re_yes.Match([]byte(exhaustVal)) {
     178                exhaust = true
     179        } else if re_no.Match([]byte(exhaustVal)) {
     180                exhaust = false
     181        } else {
     182                fmt.Fprintf(os.Stderr, "Unrecognized exhaust(-e) option '%s'\n", exhaustVal)
     183                os.Exit(1)
     184        }
     185
    163186        if clock_mode {
    164                 fmt.Fprintf(os.Stderr, "Programs does not support fixed duration mode")
     187                fmt.Fprintf(os.Stderr, "Programs does not support fixed duration mode\n")
    165188                os.Exit(1)
    166189        }
     
    215238                ws = "no"
    216239        }
    217         p.Printf("Duration (ms)           : %f\n", delta.Milliseconds() )
     240        p.Printf("Duration (ms)           : %d\n", delta.Milliseconds() )
    218241        p.Printf("Number of processors    : %d\n", nprocs )
    219242        p.Printf("Number of threads       : %d\n", nthreads )
    220         p.Printf("Total Operations(ops)   : %15d\n", stop_count )
     243        p.Printf("Total Operations(ops)   : %15d\n", (leader.idx - 1) )
    221244        p.Printf("Threads parking on wait : %s\n", ws)
    222245        p.Printf("Rechecking              : %d\n", rechecks )
    223 }
     246        p.Printf("ns per transfer         : %f\n", float64(delta.Nanoseconds()) / float64(leader.idx) )
     247}
  • benchmark/readyQ/transfer.rs

    r29d8c02 r74ec742  
    66use std::hint;
    77use std::sync::Arc;
    8 use std::sync::atomic::{AtomicUsize, Ordering};
     8use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
    99use std::time::{Instant,Duration};
    1010
     
    4444                        match val {
    4545                                "yes" => true,
     46                                "Y" => true,
     47                                "y" => true,
    4648                                "no"  => false,
     49                                "N"  => false,
     50                                "n"  => false,
    4751                                "maybe" | "I don't know" | "Can you repeat the question?" => {
    4852                                        eprintln!("Lines for 'Malcolm in the Middle' are not acceptable values of parameter 'exhaust'");
     
    6468        id: AtomicUsize,
    6569        idx: AtomicUsize,
     70        estop: AtomicBool,
    6671        seed: u128,
    6772}
     
    7277                        id: AtomicUsize::new(nthreads),
    7378                        idx: AtomicUsize::new(0),
     79                        estop: AtomicBool::new(false),
    7480                        seed: process::id() as u128
    7581                };
     
    100106}
    101107
    102 fn waitgroup(idx: usize, threads: &Vec<Arc<MyThread>>) {
     108fn waitgroup(leader: &LeaderInfo, idx: usize, threads: &Vec<Arc<MyThread>>, main_sem: &sync::Semaphore) {
    103109        let start = Instant::now();
    104         for t in threads {
     110        'outer: for t in threads {
    105111                debug!( "Waiting for :{} ({})", t.id, t.idx.load(Ordering::Relaxed) );
    106112                while t.idx.load(Ordering::Relaxed) != idx {
     
    108114                        if start.elapsed() > Duration::from_secs(5) {
    109115                                eprintln!("Programs has been blocked for more than 5 secs");
    110                                 std::process::exit(1);
     116                                leader.estop.store(true, Ordering::Relaxed);
     117                                main_sem.add_permits(1);
     118                                break 'outer;
    111119                        }
    112120                }
     
    131139        leader.idx.store(nidx, Ordering::Relaxed);
    132140
    133         if nidx as u64 > exp.stop_count {
     141        if nidx as u64 > exp.stop_count || leader.estop.load(Ordering::Relaxed) {
    134142                debug!( "Leader {} done", this.id);
    135143                main_sem.add_permits(1);
     
    139147        debug!( "====================\nLeader no {} : {}", nidx, this.id);
    140148
    141         waitgroup(nidx, threads);
     149        waitgroup(leader, nidx, threads, main_sem);
    142150
    143151        leader.next( threads.len() );
     
    192200                        wait( exhaust, &leader, &threads[me], &mut rechecks ).await;
    193201                }
    194                 if leader.idx.load(Ordering::Relaxed) as u64 > exp.stop_count { break; }
     202                if leader.idx.load(Ordering::Relaxed) as u64 > exp.stop_count || leader.estop.load(Ordering::Relaxed) { break; }
    195203        }
    196204
     
    273281        println!("Number of processors    : {}", (nprocs).to_formatted_string(&Locale::en));
    274282        println!("Number of threads       : {}", (nthreads).to_formatted_string(&Locale::en));
    275         println!("Total Operations(ops)   : {:>15}", (exp.stop_count).to_formatted_string(&Locale::en));
     283        println!("Total Operations(ops)   : {:>15}", (leader.idx.load(Ordering::Relaxed) - 1).to_formatted_string(&Locale::en));
    276284        println!("Threads parking on wait : {}", if exhaust { "yes" } else { "no" });
    277285        println!("Rechecking              : {}", rechecks );
    278 }
     286        println!("ns per transfer         : {}", ((duration.as_nanos() as f64) / leader.idx.load(Ordering::Relaxed) as f64));
     287
     288}
  • benchmark/readyQ/yield.cfa

    r29d8c02 r74ec742  
    1 #include <stdlib.h>
    2 #include <stdio.h>
    3 #include <string.h>
    4 #include <limits.h>
    5 
    6 extern "C" {
    7         #include <locale.h>
    8         #include <getopt.h>
    9 }
    10 
    11 #include <unistd.h>
    12 
    13 #include <clock.hfa>
    14 #include <time.hfa>
    15 #include <stats.hfa>
    16 
    17 #include "../benchcltr.hfa"
    18 
    19 extern bool traceHeapOn();
    20 
    21 
    22 volatile bool run = false;
    23 volatile unsigned long long global_counter;
     1#include "rq_bench.hfa"
    242
    253thread __attribute__((aligned(128))) Yielder {
    26         unsigned long long counter;
     4        unsigned long long count;
    275};
    286void ?{}( Yielder & this ) {
    29         this.counter = 0;
    30         ((thread&)this){ "Yielder Thread", *the_benchmark_cluster };
     7        ((thread&)this){ "Yielder Thread", bench_cluster };
     8        this.count = 0;
    319}
    3210
    3311void main( Yielder & this ) {
    3412        park();
    35         /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) );
     13        for() {
     14                yield();
     15                this.count++;
     16                if( clock_mode && stop) break;
     17                if(!clock_mode && this.count >= stop_count) break;
     18        }
    3619
    37         while(__atomic_load_n(&run, __ATOMIC_RELAXED)) {
    38                 yield();
    39                 this.counter++;
    40         }
    41         __atomic_fetch_add(&global_counter, this.counter, __ATOMIC_SEQ_CST);
     20        __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
    4221}
    4322
    4423int main(int argc, char * argv[]) {
    45         unsigned num_io = 1;
    46         io_context_params params;
    47 
    4824        cfa_option opt[] = {
    49                 BENCH_OPT_CFA
     25                BENCH_OPT
    5026        };
    51         int opt_cnt = sizeof(opt) / sizeof(cfa_option);
    52 
    53         char **left;
    54         parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\ncforall yield benchmark", left );
     27        BENCH_OPT_PARSE("cforall yield benchmark");
    5528
    5629        {
    57                 printf("Running %d threads on %d processors for %f seconds\n", nthreads, nprocs, duration);
     30                unsigned long long global_counter = 0;
    5831
    5932                Time start, end;
    60                 BenchCluster cl = { num_io, params, CFA_STATS_READY_Q };
     33                BenchCluster bc = { nprocs };
    6134                {
    62                         BenchProc procs[nprocs];
    63                         {
    64                                 Yielder threads[nthreads];
    65                                 printf("Starting\n");
     35                        threads_left = nthreads;
     36                        Yielder threads[nthreads];
     37                        printf("Starting\n");
    6638
    67                                 bool is_tty = isatty(STDOUT_FILENO);
    68                                 start = timeHiRes();
    69                                 run = true;
     39                        bool is_tty = isatty(STDOUT_FILENO);
     40                        start = timeHiRes();
    7041
    71                                 for(i; nthreads) {
    72                                         unpark( threads[i] );
    73                                 }
    74                                 wait(duration, start, end, is_tty);
     42                        for(i; nthreads) {
     43                                unpark( threads[i] );
     44                        }
     45                        wait(start, is_tty);
    7546
    76                                 run = false;
    77                                 end = timeHiRes();
    78                                 printf("\nDone\n");
     47                        stop = true;
     48                        end = timeHiRes();
     49                        printf("\nDone\n");
     50
     51                        for(i; nthreads) {
     52                                Yielder & y = join( threads[i] );
     53                                global_counter += y.count;
    7954                        }
    8055                }
    8156
    82                 printf("Duration (ms)       : %'ld\n", (end - start)`dms);
    83                 printf("Number of processors: %'d\n", nprocs);
    84                 printf("Number of threads   : %'d\n", nthreads);
    85                 printf("Total yields        : %'15llu\n", global_counter);
    86                 printf("Yields per second   : %'18.2lf\n", ((double)global_counter) / (end - start)`s);
    87                 printf("ns per yields       : %'18.2lf\n", ((double)(end - start)`ns) / global_counter);
    88                 printf("Yields per procs    : %'15llu\n", global_counter / nprocs);
    89                 printf("Yields/sec/procs    : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s);
    90                 printf("ns per yields/procs : %'18.2lf\n", ((double)(end - start)`ns) / (global_counter / nprocs));
     57                printf("Duration (ms)        : %'ld\n", (end - start)`dms);
     58                printf("Number of processors : %'d\n", nprocs);
     59                printf("Number of threads    : %'d\n", nthreads);
     60                printf("Total Operations(ops): %'15llu\n", global_counter);
     61                printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / (end - start)`s);
     62                printf("ns per ops           : %'18.2lf\n", (end - start)`dns / global_counter);
     63                printf("Ops per threads      : %'15llu\n", global_counter / nthreads);
     64                printf("Ops per procs        : %'15llu\n", global_counter / nprocs);
     65                printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s);
     66                printf("ns per ops/procs     : %'18.2lf\n", (end - start)`dns / (global_counter / nprocs));
    9167                fflush(stdout);
    9268        }
  • benchmark/readyQ/yield.cpp

    r29d8c02 r74ec742  
    1 #include <cassert>
    2 #include <cstdlib>
    3 #include <cstdio>
    4 #include <cstring>
    5 #include <climits>
    6 
    7 extern "C" {
    8         #include <locale.h>
    9         #include <getopt.h>
    10 }
    11 
    12 #include <unistd.h>
    13 
    14 #include <chrono>
    15 
    16 using Clock = std::chrono::high_resolution_clock;
    17 using duration_t = std::chrono::duration<double>;
    18 using std::chrono::nanoseconds;
    19 
    20 
    21 template<typename Ratio, typename T>
    22 T duration_cast(T seconds) {
    23         return std::chrono::duration_cast<std::chrono::duration<T, Ratio>>(std::chrono::duration<T>(seconds)).count();
    24 }
     1#include "rq_bench.hpp"
     2#include <libfibre/fibre.h>
    253
    264volatile bool run = false;
    275volatile unsigned long long global_counter;
    286
    29 #include "libfibre/fibre.h"
    307
    31 FredBarrier * barrier;
    32 struct __attribute__((aligned(128))) counter_t {
    33         int value = 0;
    34 };
     8void fibre_main() {
     9        fibre_park();
     10        unsigned long long count = 0;
     11        for(;;) {
     12                Fibre::yield();
     13                count++;
     14                if( clock_mode && stop) break;
     15                if(!clock_mode && count >= stop_count) break;
     16        }
    3517
    36 void fibre_main( counter_t * counter ) {
    37         barrier->wait();
    38         // /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) );
    39 
    40         while(__atomic_load_n(&run, __ATOMIC_RELAXED)) {
    41                 Fibre::forceYield();
    42                 // fibre_yield();
    43                 counter->value++;
    44         }
    45         __atomic_fetch_add(&global_counter, counter->value, __ATOMIC_SEQ_CST);
     18        __atomic_fetch_add(&global_counter, count, __ATOMIC_SEQ_CST);
     19        __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
    4620}
    4721
    4822int main(int argc, char * argv[]) {
    49         double duration = 5;
    50         int nprocs = 1;
    51         int nthreads = 1;
    52 
    53         std::cout.imbue(std::locale(""));
    54         setlocale(LC_ALL, "");
    55 
    56         for(;;) {
    57                 static struct option options[] = {
    58                         {"duration",  required_argument, 0, 'd'},
    59                         {"nprocs",    required_argument, 0, 'p'},
    60                         {"nthreads",  required_argument, 0, 't'},
    61                         {0, 0, 0, 0}
    62                 };
    63 
    64                 int idx = 0;
    65                 int opt = getopt_long(argc, argv, "d:p:t:", options, &idx);
    66 
    67                 const char * arg = optarg ? optarg : "";
    68                 char * end;
    69                 switch(opt) {
    70                         case -1:
    71                                 goto run;
    72                         // Numeric Arguments
    73                         case 'd':
    74                                 duration = strtod(arg, &end);
    75                                 if(*end != '\0') {
    76                                         fprintf(stderr, "Duration must be a valid double, was %s\n", arg);
    77                                         goto usage;
    78                                 }
    79                                 break;
    80                         case 't':
    81                                 nthreads = strtoul(arg, &end, 10);
    82                                 if(*end != '\0' || nthreads < 1) {
    83                                         fprintf(stderr, "Number of threads must be a positive integer, was %s\n", arg);
    84                                         goto usage;
    85                                 }
    86                                 break;
    87                         case 'p':
    88                                 nprocs = strtoul(arg, &end, 10);
    89                                 if(*end != '\0' || nprocs < 1) {
    90                                         fprintf(stderr, "Number of processors must be a positive integer, was %s\n", arg);
    91                                         goto usage;
    92                                 }
    93                                 break;
    94                         // Other cases
    95                         default: /* ? */
    96                                 fprintf( stderr, "Unkown option '%c'\n", opt);
    97                         usage:
    98                                 fprintf( stderr, "Usage: %s [options]\n", argv[0]);
    99                                 fprintf( stderr, "\n" );
    100                                 fprintf( stderr, "  -d, --duration=DURATION  Duration of the experiment, in seconds\n" );
    101                                 fprintf( stderr, "  -t, --nthreads=NTHREADS  Number of kernel threads\n" );
    102                                 fprintf( stderr, "  -q, --nqueues=NQUEUES    Number of queues per threads\n" );
    103                                 exit(1);
    104                 }
    105         }
    106         run:
     23        option_t opt[] = {
     24                BENCH_OPT
     25        };
     26        BENCH_OPT_PARSE("libfibre yield benchmark");
    10727
    10828        {
    10929                printf("Running %d threads on %d processors for %lf seconds\n", nthreads, nprocs, duration);
    11030
    111                 FibreInit();
    112                 barrier = new FredBarrier(nthreads + 1);
     31                FibreInit(1, nprocs);
     32                uint64_t start, end;
    11333                {
    114                         Context::CurrCluster().addWorkers(nprocs);
    115                         {
    116                                 counter_t counters[nthreads];
    117                                 Fibre threads[nthreads];
    118                                 for(int i = 0; i < nthreads; i++) {
    119                                         threads[i].run(fibre_main, &counters[i]);
    120                                 }
    121                                 printf("Starting\n");
    122                                 bool is_tty = isatty(STDOUT_FILENO);
    123                                 auto before = Clock::now();
    124                                 run = true;
     34                        threads_left = nthreads;
     35                        Fibre * threads[nthreads];
     36                        for(unsigned i = 0; i < nthreads; i++) {
     37                                threads[i] = new Fibre();
     38                                threads[i]->run(fibre_main);
     39                        }
     40                        printf("Starting\n");
     41                        bool is_tty = isatty(STDOUT_FILENO);
     42                        start = timeHiRes();
    12543
    126                                 barrier->wait();
    127                                 for(;;) {
    128                                         usleep(500'000);
    129                                         auto now = Clock::now();
    130                                         duration_t durr = now - before;
    131                                         if( durr.count() > duration ) {
    132                                                 break;
    133                                         }
    134                                         if(is_tty) {
    135                                                 std::cout << "\r" << std::setprecision(4) << durr.count();
    136                                                 std::cout.flush();
    137                                         }
    138                                 }
     44                        for(unsigned i = 0; i < nthreads; i++ ) {
     45                                fibre_unpark( threads[i] );
     46                        }
     47                        wait<Fibre>(start, is_tty);
    13948
    140                                 auto after = Clock::now();
    141                                 duration_t durr = after - before;
    142                                 duration = durr.count();
    143                                 run = false;
    144                                 printf("\nDone\n");
    145                                 for(auto & thread : threads) {
    146                                         thread.join();
    147                                 }
    148 
    149                                 // for(const auto & counter : counters) {
    150                                 //      std::cout << counter.value << std::endl;
    151                                 // }
     49                        stop = true;
     50                        end = timeHiRes();
     51                        for(unsigned i = 0; i < nthreads; i++ ) {
     52                                fibre_join( threads[i], nullptr );
    15253                        }
    15354                }
    15455
    155                 auto dur_nano = duration_cast<std::nano>(duration);
    156                 auto dur_dms  = duration_cast<std::milli>(duration);
    157 
    158                 printf("Duration (ms)       : %'.2lf\n", dur_dms );
    159                 printf("Total yields        : %'15llu\n", global_counter );
    160                 printf("Yields per procs    : %'15llu\n", global_counter / nprocs );
    161                 printf("Yields per second   : %'18.2lf\n", ((double)global_counter) / duration );
    162                 printf("Yields/sec/procs    : %'18.2lf\n", (((double)global_counter) / nprocs) / duration );
    163                 printf("ns per yields       : %'18.2lf\n", dur_nano / global_counter );
    164                 printf("ns per yields/procs : %'18.2lf\n", dur_nano / (global_counter / nprocs) );
    165 
     56                printf("Duration (ms)        : %'ld\n", to_miliseconds(end - start));
     57                printf("Number of processors : %'d\n", nprocs);
     58                printf("Number of threads    : %'d\n", nthreads);
     59                printf("Total Operations(ops): %'15llu\n", global_counter);
     60                printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / to_fseconds(end - start));
     61                printf("ns per ops           : %'18.2lf\n", ((double)(end - start)) / global_counter);
     62                printf("Ops per threads      : %'15llu\n", global_counter / nthreads);
     63                printf("Ops per procs        : %'15llu\n", global_counter / nprocs);
     64                printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / to_fseconds(end - start));
     65                printf("ns per ops/procs     : %'18.2lf\n", ((double)(end - start)) / (global_counter / nprocs));
     66                fflush(stdout);
    16667        }
    16768}
  • benchmark/readyQ/yield.rs

    r29d8c02 r74ec742  
    9090        });
    9191
    92         println!("Duration (ms)       : {}", (duration.as_millis()).to_formatted_string(&Locale::en));
    93         println!("Number of processors: {}", (nprocs).to_formatted_string(&Locale::en));
    94         println!("Number of threads   : {}", (nthreads).to_formatted_string(&Locale::en));
    95         println!("Total yields        : {:>15}", (global_counter).to_formatted_string(&Locale::en));
    96         println!("Yields per second   : {:>15}", (((global_counter as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
    97         println!("ns per yields       : {:>15}", ((duration.as_nanos() as f64 / global_counter as f64) as u64).to_formatted_string(&Locale::en));
    98         println!("Yields per threads  : {:>15}", (global_counter / nthreads as u64).to_formatted_string(&Locale::en));
    99         println!("Yields per procs    : {:>15}", (global_counter / nprocs as u64).to_formatted_string(&Locale::en));
    100         println!("Yields/sec/procs    : {:>15}", ((((global_counter as f64) / nprocs as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
    101         println!("ns per yields/procs : {:>15}", ((duration.as_nanos() as f64 / (global_counter as f64 / nprocs as f64)) as u64).to_formatted_string(&Locale::en));
     92        println!("Duration (ms)        : {}", (duration.as_millis()).to_formatted_string(&Locale::en));
     93        println!("Number of processors : {}", (nprocs).to_formatted_string(&Locale::en));
     94        println!("Number of threads    : {}", (nthreads).to_formatted_string(&Locale::en));
     95        println!("Total Operations(ops): {:>15}", (global_counter).to_formatted_string(&Locale::en));
     96        println!("Ops per second       : {:>15}", (((global_counter as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
     97        println!("ns per ops           : {:>15}", ((duration.as_nanos() as f64 / global_counter as f64) as u64).to_formatted_string(&Locale::en));
     98        println!("Ops per threads      : {:>15}", (global_counter / nthreads as u64).to_formatted_string(&Locale::en));
     99        println!("Ops per procs        : {:>15}", (global_counter / nprocs as u64).to_formatted_string(&Locale::en));
     100        println!("Ops/sec/procs        : {:>15}", ((((global_counter as f64) / nprocs as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
     101        println!("ns per ops/procs    : {:>15}", ((duration.as_nanos() as f64 / (global_counter as f64 / nprocs as f64)) as u64).to_formatted_string(&Locale::en));
    102102}
Note: See TracChangeset for help on using the changeset viewer.