v / vlib / sync / bench / channel_bench_v.v
66 lines · 63 sloc · 1.49 KB · 017ace6ea7402430a992aa0820d5e472ebca74c7
Raw
1// Channel Benchmark
2//
3// `nobj` integers are sent thru a channel with queue length`buflen`
4// using `nsend` sender threads and `nrec` receiver threads.
5//
6// The receive threads add all received numbers and send them to the
7// main thread where the total sum is compare to the expected value.
8import time
9import os
10
11fn do_rec(ch chan int, resch chan i64, n int) {
12 mut sum := i64(0)
13 for _ in 0 .. n {
14 sum += <-ch
15 }
16 println(sum)
17 resch <- sum
18}
19
20fn do_send(ch chan int, start int, end int) {
21 for i in start .. end {
22 ch <- i
23 }
24}
25
26fn main() {
27 if os.args.len != 5 {
28 eprintln('usage:\n\t${os.args[0]} <nsend> <nrec> <buflen> <nobj>')
29 exit(1)
30 }
31 nsend := os.args[1].int()
32 nrec := os.args[2].int()
33 buflen := os.args[3].int()
34 nobj := os.args[4].int()
35 stopwatch := time.new_stopwatch()
36 ch := chan int{cap: buflen}
37 resch := chan i64{}
38 mut no := nobj
39 for i in 0 .. nrec {
40 n := no / (nrec - i)
41 spawn do_rec(ch, resch, n)
42 no -= n
43 }
44 $if debug {
45 assert no == 0
46 }
47 no = nobj
48 for i in 0 .. nsend {
49 n := no / (nsend - i)
50 end := no
51 no -= n
52 spawn do_send(ch, no, end)
53 }
54 assert no == 0
55 mut sum := i64(0)
56 for _ in 0 .. nrec {
57 sum += <-resch
58 }
59 elapsed := stopwatch.elapsed()
60 rate := f64(nobj) / elapsed * time.microsecond
61 println('${nobj} objects in ${f64(elapsed) / time.second} s (${rate:.2f} objs/µs)')
62 // use sum formula by Gauß to calculate the expected result
63 expected_sum := i64(nobj) * (nobj - 1) / 2
64 println('got: ${sum}, expected: ${expected_sum}')
65 assert sum == expected_sum
66}
67