comparison pkg/octree/builder.go @ 2478:930ca9c4e2a7 octree-diff

Fixed concurrent octree builder. The iso line cuts are now in the same quantity order of line segments but still differ. Need to have a closer look once we serve the data.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 28 Feb 2019 12:34:47 +0100
parents 9b1f0edf5fdc
children 1ec4c5633eb6
comparison
equal deleted inserted replaced
2477:9b1f0edf5fdc 2478:930ca9c4e2a7
16 import ( 16 import (
17 "bytes" 17 "bytes"
18 "encoding/binary" 18 "encoding/binary"
19 "io" 19 "io"
20 "log" 20 "log"
21 "runtime"
21 "sync" 22 "sync"
22 "sync/atomic" 23 "sync/atomic"
23 24
24 "github.com/golang/snappy" 25 "github.com/golang/snappy"
25 ) 26 )
75 triangles := make([]int32, len(tb.t.Triangles)) 76 triangles := make([]int32, len(tb.t.Triangles))
76 for i := range triangles { 77 for i := range triangles {
77 triangles[i] = int32(i) 78 triangles[i] = int32(i)
78 } 79 }
79 80
81 n := runtime.NumCPU()
82
83 steps := make(chan buildStep)
84
85 var wg sync.WaitGroup
86 for i := 0; i < n; i++ {
87 wg.Add(1)
88 go func() {
89 defer wg.Done()
90 for step := range steps {
91 step(steps)
92 }
93 }()
94 }
95
96 tb.index = append(tb.index, 0)
97
98 root := func(int32) {
99 close(steps)
100 }
101
102 steps <- tb.buildConcurrent(
103 triangles,
104 tb.t.Min, tb.t.Max,
105 0,
106 root)
107
108 wg.Wait()
109
80 /* 110 /*
81 n := runtime.NumCPU() 111 tb.buildRecursive(triangles, tb.t.Min, tb.t.Max, 0)
82
83 steps := make(chan buildStep, n)
84
85 var wg sync.WaitGroup
86 for i := 0; i < n; i++ {
87 wg.Add(1)
88 go func() {
89 defer wg.Done()
90 for step := range steps {
91 step(steps)
92 }
93 }()
94 }
95
96 tb.index = append(tb.index, 0)
97
98 root := func(int32) {
99 close(steps)
100 }
101
102 steps <- tb.buildConcurrent(
103 triangles,
104 tb.t.Min, tb.t.Max,
105 0,
106 root)
107
108 wg.Wait()
109 */ 112 */
110
111 tb.buildRecursive(triangles, tb.t.Min, tb.t.Max, 0)
112 tb.index[0] = int32(len(tb.index)) 113 tb.index[0] = int32(len(tb.index))
113 log.Printf("info: num nodes: %d\n", tb.index[0]) 114 log.Printf("info: num nodes: %d\n", tb.index[0])
114 log.Printf("info: nodes: %d leaves: %d index %d\n", 115 log.Printf("info: nodes: %d leaves: %d index %d\n",
115 tb.nodes, tb.leaves, tb.index[0]) 116 tb.nodes, tb.leaves, tb.index[0])
116 } 117 }
123 ) buildStep { 124 ) buildStep {
124 125
125 return func(steps chan buildStep) { 126 return func(steps chan buildStep) {
126 127
127 // none concurrent for small parts. 128 // none concurrent for small parts.
128 if len(triangles) < 1024 || depth > 8 { 129 if len(triangles) <= 1024 || depth > 8 {
129 parent(tb.buildRecursive(triangles, min, max, depth)) 130 parent(tb.buildRecursive(triangles, min, max, depth))
130 return 131 return
131 } 132 }
132 133
133 bbox := Interpolate(min, max) 134 bbox := Interpolate(min, max)
162 quandrants[i] = append(quandrants[i], tri) 163 quandrants[i] = append(quandrants[i], tri)
163 } 164 }
164 } 165 }
165 } 166 }
166 167
167 var used int32 168 used := new(int32)
168 for i := range quandrants { 169 for i := range quandrants {
169 if len(quandrants[i]) > 0 { 170 if len(quandrants[i]) > 0 {
170 used++ 171 *used++
171 } 172 }
172 } 173 }
173 174
174 pos := tb.allocNode() 175 pos := tb.allocNode()
175 176
176 for i := range quandrants { 177 for i := range quandrants {
177 if len(quandrants[i]) > 0 { 178 if len(quandrants[i]) > 0 {
178 j := i 179 j := int32(i)
179 parent := func(v int32) { 180 parent := func(v int32) {
180 tb.index[j] = v 181 tb.index[pos+j] = v
181 if atomic.AddInt32(&used, -1) == 0 { 182 if atomic.AddInt32(used, -1) == 0 {
182 parent(pos) 183 parent(pos)
183 } 184 }
184 } 185 }
185 step := tb.buildConcurrent( 186 step := tb.buildConcurrent(
186 quandrants[j], 187 quandrants[i],
187 bboxes[j][0], bboxes[j][1], 188 bboxes[i][0], bboxes[i][1],
188 depth+1, 189 depth+1,
189 parent) 190 parent)
190 select { 191 select {
191 case steps <- step: 192 case steps <- step:
192 default: 193 default: