Changes in / [fe97de26:0285efe]
- Files:
-
- 4 deleted
- 7 edited
-
benchmark/Cargo.toml.in (deleted)
-
benchmark/Makefile.am (modified) (1 diff)
-
benchmark/bench.rs (deleted)
-
benchmark/readyQ/bench.go (modified) (3 diffs)
-
benchmark/readyQ/cycle.rs (modified) (5 diffs)
-
benchmark/readyQ/locality.cfa (deleted)
-
benchmark/readyQ/locality.go (modified) (9 diffs)
-
benchmark/readyQ/locality.rs (deleted)
-
configure.ac (modified) (2 diffs)
-
libcfa/src/parseargs.cfa (modified) (1 diff)
-
libcfa/src/parseargs.hfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
benchmark/Makefile.am
rfe97de26 r0285efe 522 522 size-cfa$(EXEEXT): 523 523 $(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/size/size.cfa 524 525 ## =========================================================================================================526 527 %-tokio$(EXEEXT): $(srcdir)/readyQ/%.rs $(srcdir)/bench.rs528 cd $(builddir) && cargo build --release529 cp $(builddir)/target/release/$(basename $@) $@ -
benchmark/readyQ/bench.go
rfe97de26 r0285efe 5 5 "flag" 6 6 "fmt" 7 "log"8 7 "os" 9 8 "runtime" 10 "runtime/pprof"11 9 "sync/atomic" 12 10 "time" … … 45 43 } 46 44 47 func bench_init() func(){45 func bench_init() { 48 46 nprocsOpt := flag.Int("p", 1, "The number of processors") 49 47 nthreadsOpt := flag.Int("t", 1, "The number of threads") 50 48 durationOpt := flag.Float64("d", 0, "Duration of the experiment in seconds") 51 49 stopOpt := flag.Uint64("i", 0, "Duration of the experiment in iterations") 52 cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")53 50 54 51 flag.Parse() … … 75 72 76 73 runtime.GOMAXPROCS(nprocs) 77 78 if (*cpuprofile) != "" {79 f, err := os.Create(*cpuprofile)80 if err != nil {81 log.Fatal(err)82 }83 pprof.StartCPUProfile(f)84 }85 86 return func() {87 if (*cpuprofile) != "" {88 pprof.StopCPUProfile()89 }90 }91 74 } -
benchmark/readyQ/cycle.rs
rfe97de26 r0285efe 1 #[cfg(any( 2 feature = "sync time rt-threaded", 3 ))] 4 5 extern crate tokio; 6 7 use std::io::{self, Write}; 1 8 use std::sync::Arc; 2 use std::sync::atomic:: Ordering;3 use std::time:: Instant;9 use std::sync::atomic::{AtomicU64, AtomicBool,Ordering}; 10 use std::time::{Instant,Duration}; 4 11 5 12 use tokio::runtime::Builder; 6 13 use tokio::sync; 7 14 use tokio::time; 15 16 extern crate isatty; 17 use isatty::stdout_isatty; 18 19 extern crate num_format; 20 use num_format::{Locale, ToFormattedString}; 21 22 extern crate clap; 8 23 use clap::{Arg, App}; 9 use num_format::{Locale, ToFormattedString}; 10 11 #[path = "../bench.rs"] 12 mod bench; 13 14 // ================================================== 24 25 use std::cell::UnsafeCell; 26 use std::mem::MaybeUninit; 27 use std::ops; 28 29 pub struct InitializeCell<T> { 30 inner: UnsafeCell<MaybeUninit<T>>, 31 } 32 33 unsafe impl<T> Sync for InitializeCell<T> {} 34 35 impl<T> InitializeCell<T> { 36 pub const unsafe fn new_uninitialized() -> InitializeCell<T> { 37 InitializeCell { 38 inner: UnsafeCell::new(MaybeUninit::uninit()), 39 } 40 } 41 pub const fn new(init: T) -> InitializeCell<T> { 42 InitializeCell { 43 inner: UnsafeCell::new(MaybeUninit::new(init)), 44 } 45 } 46 pub unsafe fn init(&self, init: T) { 47 (*self.inner.get()) = MaybeUninit::new(init); 48 } 49 } 50 51 impl<T> ops::Deref for InitializeCell<T> { 52 type Target = T; 53 fn deref(&self) -> &T { 54 unsafe { 55 &*(*self.inner.get()).as_ptr() 56 } 57 } 58 } 59 60 static CLOCK_MODE: InitializeCell<bool> = unsafe { InitializeCell::new_uninitialized() }; 61 static STOP_COUNT: InitializeCell<u64> = unsafe { InitializeCell::new_uninitialized() }; 62 static DURATION: InitializeCell<f64> = unsafe { InitializeCell::new_uninitialized() }; 63 static STOP : AtomicBool = AtomicBool::new(false); 64 static THREADS_LEFT : AtomicU64 = AtomicU64 ::new(10); 65 15 66 struct Partner { 16 67 sem: sync::Semaphore, … … 18 69 } 19 70 20 async fn partner_main( idx: usize, others: Arc<Vec<Arc<Partner>>>, exp: Arc<bench::BenchData> ) -> u64{71 async fn partner_main(result: sync::oneshot::Sender<u64>, idx: usize, others: Arc<Vec<Arc<Partner>>> ) { 21 72 let this = &others[idx]; 22 73 let mut count:u64 = 0; … … 26 77 count += 1; 27 78 28 if exp.clock_mode && exp.stop.load(Ordering::Relaxed) { break; } 29 if !exp.clock_mode && count >= exp.stop_count { break; } 30 } 31 32 exp.threads_left.fetch_sub(1, Ordering::SeqCst); 33 count 34 } 35 36 // ================================================== 79 if *CLOCK_MODE && STOP.load(Ordering::Relaxed) { break; } 80 if !*CLOCK_MODE && count >= *STOP_COUNT { break; } 81 } 82 83 THREADS_LEFT.fetch_sub(1, Ordering::SeqCst); 84 result.send( count ).unwrap(); 85 } 86 87 fn prep(nthreads: usize, tthreads: usize) -> Vec<Arc<Partner>> { 88 let mut thddata = Vec::with_capacity(tthreads); 89 for i in 0..tthreads { 90 let pi = (i + nthreads) % tthreads; 91 thddata.push(Arc::new(Partner{ 92 sem: sync::Semaphore::new(0), 93 next: pi, 94 })); 95 } 96 return thddata; 97 } 98 99 async fn wait(start: &Instant, is_tty: bool) { 100 loop { 101 time::sleep(Duration::from_micros(100000)).await; 102 let delta = start.elapsed(); 103 if is_tty { 104 print!(" {:.1}\r", delta.as_secs_f32()); 105 io::stdout().flush().unwrap(); 106 } 107 if *CLOCK_MODE && delta >= Duration::from_secs_f64(*DURATION) { 108 break; 109 } 110 else if !*CLOCK_MODE && THREADS_LEFT.load(Ordering::Relaxed) == 0 { 111 break; 112 } 113 } 114 } 115 37 116 fn main() { 38 117 let options = App::new("Cycle Tokio") 39 .args(&bench::args()) 118 .arg(Arg::with_name("duration") .short("d").long("duration") .takes_value(true).default_value("5").help("Duration of the experiments in seconds")) 119 .arg(Arg::with_name("iterations").short("i").long("iterations").takes_value(true).conflicts_with("duration").help("Number of iterations of the experiments")) 120 .arg(Arg::with_name("nthreads") .short("t").long("nthreads") .takes_value(true).default_value("1").help("Number of threads to use")) 121 .arg(Arg::with_name("nprocs") .short("p").long("nprocs") .takes_value(true).default_value("1").help("Number of processors to use")) 40 122 .arg(Arg::with_name("ringsize") .short("r").long("ringsize") .takes_value(true).default_value("1").help("Number of threads in a cycle")) 41 123 .get_matches(); … … 45 127 let nprocs = options.value_of("nprocs").unwrap().parse::<usize>().unwrap(); 46 128 47 let tthreads = nthreads * ring_size; 48 let exp = Arc::new(bench::BenchData::new(options, tthreads)); 129 if options.is_present("iterations") { 130 unsafe{ 131 CLOCK_MODE.init( false ); 132 STOP_COUNT.init( options.value_of("iterations").unwrap().parse::<u64>().unwrap() ); 133 } 134 } 135 else { 136 unsafe{ 137 CLOCK_MODE.init(true); 138 DURATION .init(options.value_of("duration").unwrap().parse::<f64>().unwrap()); 139 } 140 } 49 141 50 142 let s = (1000000 as u64).to_formatted_string(&Locale::en); 51 143 assert_eq!(&s, "1,000,000"); 52 144 53 let thddata : Arc<Vec<Arc<Partner>>> = Arc::new( 54 (0..tthreads).map(|i| { 55 let pi = (i + nthreads) % tthreads; 56 Arc::new(Partner{ 57 sem: sync::Semaphore::new(0), 58 next: pi, 59 }) 60 }).collect() 61 ); 145 146 let tthreads = nthreads * ring_size; 147 THREADS_LEFT.store(tthreads as u64, Ordering::SeqCst); 148 let thddata = Arc::new(prep(nthreads, tthreads)); 62 149 63 150 let mut global_counter :u64 = 0; … … 70 157 71 158 runtime.block_on(async { 72 let threads: Vec<_> = (0..tthreads).map(|i| { 73 tokio::spawn(partner_main(i, thddata.clone(), exp.clone())) 74 }).collect(); 75 println!("Starting"); 76 77 let start = Instant::now(); 78 79 for i in 0..nthreads { 80 thddata[i].sem.add_permits(1); 81 } 82 83 duration = exp.wait(&start).await; 84 85 println!("\nDone"); 86 87 for i in 0..tthreads { 88 thddata[i].sem.add_permits(1); 89 } 90 91 for t in threads { 92 global_counter += t.await.unwrap(); 159 let mut result : Vec<sync::oneshot::Receiver::<u64>> = Vec::with_capacity(tthreads); 160 { 161 let mut threads = Vec::with_capacity(tthreads); 162 for i in 0..tthreads { 163 let (s, r) = sync::oneshot::channel::<u64>(); 164 result.push(r); 165 threads.push(tokio::spawn(partner_main(s, i, thddata.clone()))); 166 } 167 println!("Starting"); 168 169 let is_tty = stdout_isatty(); 170 let start = Instant::now(); 171 172 for i in 0..nthreads { 173 thddata[i].sem.add_permits(1); 174 } 175 176 wait(&start, is_tty).await; 177 178 STOP.store(true, Ordering::SeqCst); 179 duration = start.elapsed(); 180 181 println!("\nDone"); 182 183 for i in 0..tthreads { 184 thddata[i].sem.add_permits(1); 185 } 186 187 for _ in 0..tthreads { 188 global_counter += result.pop().unwrap().await.unwrap(); 189 } 93 190 } 94 191 }); -
benchmark/readyQ/locality.go
rfe97de26 r0285efe 18 18 // ================================================== 19 19 type MyData struct { 20 _p1 [16]uint64 // padding21 20 ttid int 22 21 id int 23 22 data [] uint64 24 _p2 [16]uint64 // padding25 23 } 26 24 … … 31 29 data[i] = 0 32 30 } 33 return &MyData{ [16]uint64{0}, syscall.Gettid(), id, data,[16]uint64{0}}31 return &MyData{syscall.Gettid(), id, data} 34 32 } 35 33 … … 48 46 // ================================================== 49 47 type MyCtx struct { 50 _p1 [16]uint64 // padding51 48 s * semaphore.Weighted 52 49 d unsafe.Pointer … … 54 51 ttid int 55 52 id int 56 _p2 [16]uint64 // padding57 53 } 58 54 59 55 func NewCtx( data * MyData, id int ) (MyCtx) { 60 r := MyCtx{ [16]uint64{0},semaphore.NewWeighted(1), unsafe.Pointer(data), context.Background(), syscall.Gettid(), id,[16]uint64{0}}56 r := MyCtx{semaphore.NewWeighted(1), unsafe.Pointer(data), context.Background(), syscall.Gettid(), id} 61 57 r.s.Acquire(context.Background(), 1) 62 58 return r … … 75 71 // May exchanges data 76 72 type Spot struct { 77 _p1 [16]uint64 // padding78 73 ptr uintptr // atomic variable use fo MES 79 74 id int // id for debugging 80 _p2 [16]uint64 // padding81 75 } 82 76 … … 221 215 func main() { 222 216 // Benchmark specific command line arguments 223 work_sizeOpt := flag.Uint64("w", 2 , " Size of the array for each threads, in words (64bit)")224 countOpt := flag.Uint64("c", 2 , "Number of words to touch when working (random pick, cells can be picked more than once)")217 work_sizeOpt := flag.Uint64("w", 2 , "Number of words (uint64) per threads") 218 countOpt := flag.Uint64("c", 2 , "Number of words (uint64) to touch") 225 219 shareOpt := flag.Bool ("s", false, "Pass the work data to the next thread when blocking") 226 220 … … 245 239 channels := make([]Spot, nthreads - nprocs) // Number of spots 246 240 for i := range channels { 247 channels[i] = Spot{ [16]uint64{0},uintptr(0), i,[16]uint64{0}} // init spots241 channels[i] = Spot{uintptr(0), i} // init spots 248 242 } 249 243 … … 272 266 273 267 // Join and accumulate results 274 results:= NewResult()268 global_result := NewResult() 275 269 for i := 0; i < nthreads; i++ { 276 270 r := <- result 277 results.count += r.count278 results.gmigs += r.gmigs279 results.dmigs += r.dmigs271 global_result.count += r.count 272 global_result.gmigs += r.gmigs 273 global_result.dmigs += r.dmigs 280 274 } 281 275 … … 286 280 p.Printf("Number of threads : %d\n", nthreads); 287 281 p.Printf("Work size (64bit words): %d\n", size); 288 p.Printf("Total Operations(ops) : %15d\n", results.count)289 p.Printf("Total G Migrations : %15d\n", results.gmigs)290 p.Printf("Total D Migrations : %15d\n", results.dmigs)291 p.Printf("Ops per second : %18.2f\n", float64( results.count) / delta.Seconds())292 p.Printf("ns per ops : %18.2f\n", float64(delta.Nanoseconds()) / float64( results.count))293 p.Printf("Ops per threads : %15d\n", results.count / uint64(nthreads))294 p.Printf("Ops per procs : %15d\n", results.count / uint64(nprocs))295 p.Printf("Ops/sec/procs : %18.2f\n", (float64( results.count) / float64(nprocs)) / delta.Seconds())296 p.Printf("ns per ops/procs : %18.2f\n", float64(delta.Nanoseconds()) / (float64( results.count) / float64(nprocs)))297 } 282 p.Printf("Total Operations(ops) : %15d\n", global_result.count) 283 p.Printf("Total G Migrations : %15d\n", global_result.gmigs) 284 p.Printf("Total D Migrations : %15d\n", global_result.dmigs) 285 p.Printf("Ops per second : %18.2f\n", float64(global_result.count) / delta.Seconds()) 286 p.Printf("ns per ops : %18.2f\n", float64(delta.Nanoseconds()) / float64(global_result.count)) 287 p.Printf("Ops per threads : %15d\n", global_result.count / uint64(nthreads)) 288 p.Printf("Ops per procs : %15d\n", global_result.count / uint64(nprocs)) 289 p.Printf("Ops/sec/procs : %18.2f\n", (float64(global_result.count) / float64(nprocs)) / delta.Seconds()) 290 p.Printf("ns per ops/procs : %18.2f\n", float64(delta.Nanoseconds()) / (float64(global_result.count) / float64(nprocs))) 291 } -
configure.ac
rfe97de26 r0285efe 295 295 # Some of our makefile don't need to be distributed 296 296 AM_CONDITIONAL([CFORALL_DISTRIBUTE], [test -e $TOP_SRCDIR/autogen.sh]) 297 AM_COND_IF([CFORALL_DISTRIBUTE], [298 AC_CONFIG_FILES([297 AM_COND_IF([CFORALL_DISTRIBUTE], 298 [AC_CONFIG_FILES([ 299 299 longrun_tests/Makefile 300 300 benchmark/Makefile … … 302 302 tools/Makefile 303 303 tools/prettyprinter/Makefile 304 ]) 305 306 AC_OUTPUT(benchmark/Cargo.toml) 307 ]) 304 ])]) 308 305 309 306 AC_CONFIG_LINKS([tests/test.py:tests/test.py]) -
libcfa/src/parseargs.cfa
rfe97de26 r0285efe 185 185 } 186 186 187 bool parse_truefalse(const char * arg, bool & value) {188 if(strcmp(arg, "true") == 0) {189 value = true;190 return true;191 }192 193 if(strcmp(arg, "false") == 0) {194 value = false;195 return true;196 }197 198 return false;199 }200 201 187 bool parse_settrue (const char *, bool & value ) { 202 188 value = true; -
libcfa/src/parseargs.hfa
rfe97de26 r0285efe 37 37 void print_args_usage(int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)); 38 38 39 bool parse_yesno (const char *, bool & ); 40 bool parse_truefalse(const char *, bool & ); 41 bool parse_settrue (const char *, bool & ); 42 bool parse_setfalse (const char *, bool & ); 39 bool parse_yesno (const char *, bool & ); 40 bool parse_settrue (const char *, bool & ); 41 bool parse_setfalse(const char *, bool & ); 43 42 44 43 bool parse(const char *, const char * & );
Note:
See TracChangeset
for help on using the changeset viewer.