func main() { runtime.GOMAXPROCS(runtime.NumCPU()) flag.Parse() if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } if *procs < 1 { log.Fatalf("Procs (%v) needs to be >= 1", *procs) } fmt.Printf("P6 %v %v 255 ", *width, *height) bytes := make([]byte, 3**width**height) g := vector.Vector{X: -5.5, Y: -16, Z: 0}.Normalize() a := vector.Vector{X: 0, Y: 0, Z: 1}.CrossProduct(g).Normalize().Scale(0.002) b := g.CrossProduct(a).Normalize().Scale(0.002) c := a.Add(b).Scale(-256).Add(g) rows := make(chan row, *height) var wg sync.WaitGroup wg.Add(*procs) for i := 0; i < *procs; i++ { go worker(a, b, c, bytes, rows, &wg) } for y := (*height - 1); y >= 0; y-- { rows <- row(y) } close(rows) wg.Wait() if _, err := os.Stdout.Write(bytes); err != nil { log.Panic(err) } }