@@ -9,39 +9,46 @@ import (
99)
1010
1111// --- Topology scaling: measure scheduling overhead across graph shapes and sizes ---
12+ // concurrency is goroutine pool size, can be larger than NumCPU since goroutines are lightweight
1213
1314func BenchmarkConcurrent (b * testing.B ) {
15+ numCPU := runtime .NumCPU ()
1416 for _ , n := range []int {8 , 32 , 128 , 512 } {
15- b .Run (fmt .Sprintf ("N%d" , n ), func (b * testing.B ) {
16- exec := gotaskflow .NewExecutor (uint (runtime .NumCPU ()))
17- tf := gotaskflow .NewTaskFlow ("concurrent" )
18- for i := 0 ; i < n ; i ++ {
19- tf .NewTask (fmt .Sprintf ("T%d" , i ), func () {})
20- }
21- b .ResetTimer ()
22- for i := 0 ; i < b .N ; i ++ {
23- exec .Run (tf ).Wait ()
24- }
25- })
17+ for _ , c := range []int {numCPU , numCPU * 4 , numCPU * 8 } {
18+ b .Run (fmt .Sprintf ("N%d-C%d" , n , c ), func (b * testing.B ) {
19+ exec := gotaskflow .NewExecutor (uint (c ))
20+ tf := gotaskflow .NewTaskFlow ("concurrent" )
21+ for i := 0 ; i < n ; i ++ {
22+ tf .NewTask (fmt .Sprintf ("T%d" , i ), func () {})
23+ }
24+ b .ResetTimer ()
25+ for i := 0 ; i < b .N ; i ++ {
26+ exec .Run (tf ).Wait ()
27+ }
28+ })
29+ }
2630 }
2731}
2832
2933func BenchmarkSerial (b * testing.B ) {
34+ numCPU := runtime .NumCPU ()
3035 for _ , n := range []int {8 , 32 , 128 , 512 } {
31- b .Run (fmt .Sprintf ("N%d" , n ), func (b * testing.B ) {
32- exec := gotaskflow .NewExecutor (uint (runtime .NumCPU ()))
33- tf := gotaskflow .NewTaskFlow ("serial" )
34- prev := tf .NewTask ("T0" , func () {})
35- for i := 1 ; i < n ; i ++ {
36- next := tf .NewTask (fmt .Sprintf ("T%d" , i ), func () {})
37- prev .Precede (next )
38- prev = next
39- }
40- b .ResetTimer ()
41- for i := 0 ; i < b .N ; i ++ {
42- exec .Run (tf ).Wait ()
43- }
44- })
36+ for _ , c := range []int {numCPU , numCPU * 4 } {
37+ b .Run (fmt .Sprintf ("N%d-C%d" , n , c ), func (b * testing.B ) {
38+ exec := gotaskflow .NewExecutor (uint (c ))
39+ tf := gotaskflow .NewTaskFlow ("serial" )
40+ prev := tf .NewTask ("T0" , func () {})
41+ for i := 1 ; i < n ; i ++ {
42+ next := tf .NewTask (fmt .Sprintf ("T%d" , i ), func () {})
43+ prev .Precede (next )
44+ prev = next
45+ }
46+ b .ResetTimer ()
47+ for i := 0 ; i < b .N ; i ++ {
48+ exec .Run (tf ).Wait ()
49+ }
50+ })
51+ }
4552 }
4653}
4754
@@ -65,28 +72,31 @@ func BenchmarkDiamond(b *testing.B) {
6572}
6673
6774func BenchmarkDenseLayers (b * testing.B ) {
75+ numCPU := runtime .NumCPU ()
6876 for _ , layers := range []int {4 , 8 } {
6977 for _ , width := range []int {4 , 8 } {
70- b .Run (fmt .Sprintf ("L%dxW%d" , layers , width ), func (b * testing.B ) {
71- exec := gotaskflow .NewExecutor (uint (runtime .NumCPU ()))
72- tf := gotaskflow .NewTaskFlow ("dense_layers" )
73- var curLayer , prevLayer []* gotaskflow.Task
74- for l := 0 ; l < layers ; l ++ {
75- for w := 0 ; w < width ; w ++ {
76- task := tf .NewTask (fmt .Sprintf ("T%d_%d" , l , w ), func () {})
77- for _ , p := range prevLayer {
78- p .Precede (task )
78+ for _ , c := range []int {numCPU , numCPU * 4 } {
79+ b .Run (fmt .Sprintf ("L%dxW%d-C%d" , layers , width , c ), func (b * testing.B ) {
80+ exec := gotaskflow .NewExecutor (uint (c ))
81+ tf := gotaskflow .NewTaskFlow ("dense_layers" )
82+ var curLayer , prevLayer []* gotaskflow.Task
83+ for l := 0 ; l < layers ; l ++ {
84+ for w := 0 ; w < width ; w ++ {
85+ task := tf .NewTask (fmt .Sprintf ("T%d_%d" , l , w ), func () {})
86+ for _ , p := range prevLayer {
87+ p .Precede (task )
88+ }
89+ curLayer = append (curLayer , task )
7990 }
80- curLayer = append (curLayer , task )
91+ prevLayer = curLayer
92+ curLayer = nil
8193 }
82- prevLayer = curLayer
83- curLayer = nil
84- }
85- b .ResetTimer ()
86- for i := 0 ; i < b .N ; i ++ {
87- exec .Run (tf ).Wait ()
88- }
89- })
94+ b .ResetTimer ()
95+ for i := 0 ; i < b .N ; i ++ {
96+ exec .Run (tf ).Wait ()
97+ }
98+ })
99+ }
90100 }
91101 }
92102}
0 commit comments