(해결) 어제 올린 만델브로 집합 시각화 누가 병렬처리 해보라기에
모모링러브(neosigmund)
2016-12-20 14:17
추천 1
![viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28177a16fb3dab004c86b6f1241ce450ebd83e292e9e6afef9bca29cbc34a00752b01289737a7cb03c3295d0236667ec0d54c756f6061e4369080b302]()
기초적인 실수를 하고 있었다가 우연히 발견하고 해결함 ㅇㅇ
package main
import (
"image"
"image/color"
"image/png"
"math"
"os"
"runtime"
"sync"
)
const (
path = "mandelbrot.png"
height, width = 1024, 1024
amax, amin, bmax, bmin = 2, -2, 2, -2
routines = 100
iterations = 255
contrast = 20
)
type Request struct {
X, Y int
A, B float64
}
type Response struct {
Request *Request
Color color.Gray
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
draw(process(send(), routines))
}
func send() <-chan *Request {
out := make(chan *Request)
go func() {
defer close(out)
for y := 0; y < height; y++ {
b := float64(y)/height*(bmax-bmin) + bmin
for x := 0; x < width; x++ {
a := float64(x)/width*(amax-amin) + amin
out <- &Request{x, y, a, b}
}
}
}()
return out
}
func process(in <-chan *Request, routines int) <-chan *Response {
var outs []<-chan *Response
for i := 0; i < routines; i++ {
outs = append(outs, mandelbrot(in))
}
return merge(outs...)
}
func mandelbrot(in <-chan *Request) <-chan *Response {
out := make(chan *Response)
go func() {
defer close(out)
for request := range in {
var x, y float64
a, b := request.A, request.B
response := &Response{request, color.Gray{0}}
for n := uint8(0); n < iterations; n++ {
x, y = x*x-y*y+a, 2*x*y+b
if math.Hypot(x, y) > 2 {
response.Color = color.Gray{255 - contrast*n}
break
}
}
out <- response
}
}()
return out
}
func merge(ins ...<-chan *Response) <-chan *Response {
var wg sync.WaitGroup
wg.Add(len(ins))
out := make(chan *Response)
for _, in := range ins {
go func(in <-chan *Response) {
defer wg.Done()
for response := range in {
out <- response
}
}(in)
}
go func() {
defer close(out)
wg.Wait()
}()
return out
}
func draw(in <-chan *Response) {
file, _ := os.Create(path)
defer file.Close()
img := image.NewGray(image.Rect(0, 0, width, height))
for response := range in {
img.Set(response.Request.X, response.Request.Y, response.Color)
}
png.Encode(file, img)
}
댓글 0