FAQ
I recently tried out Go and decided to write a small program which
visualises the Mandelbrot set. I wanted to try out Go's complex number
library as well as Go's concurrency support. Now I know that the proper way
to do this would be to calculate everything on the GPU using a shader
program or something like CUDA, it was merely an experiment to try out Go.
The app itself is very easy to use, press f to go to the next iteration, b
to go back and 1,2,4 and 8 to choose the number of threads calculating the
mandelbrot set. On my Macbook Air it always takes at least 50ms to 200ms
for more iterations. I think these numbers are already quite bad, there is
however no (noticeable) difference if I use 1,2 or 4 threads! I think the
CPU on my Macbook Air supports two hardware threads and two virtual ones. I
also tried to profile it only to learn that the profiler does not support
multiple threads on Mac OS right now. I will probably install Linux
sometimes, but until then I wonder if some of the experienced Go developers
can tell me why it is so slow. Code is
here: https://github.com/nightlifelover/GoMandelbrot

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Andrey mirtchovski at Nov 9, 2013 at 5:49 pm
    I suggest the first step is to make your package go-installable. rename the
    src directory to whatever the binary will be called, or just move
    everything from src/ to / and change all package imports to say "
    github.com/nightlifelover/GoMandelbrot/" + the package name. the binary
    will be called "GoMandelbrot" once installed by the go tool. here are a
    couple of changes in main.go to give you an example:

    - "inputoutput"
    + "github.com/nightlifelover/GoMandelbrot/inputoutput"
    + "github.com/nightlifelover/GoMandelbrot/mandelbrot"
    - "mandelbrot"


    next order of work is to fix your code so that it compiles, for example,
    where does 'height' here come from?

    https://github.com/nightlifelover/GoMandelbrot/blob/master/src/mandelbrot/mandelbrot.go#L70

    if you make it easier for people to help, you'll definitely get more help :)

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jonathan K Hanks at Nov 9, 2013 at 10:35 pm
    Nils,

    Are you setting the GOMAXPROCS environment variable? By default go will
    run everything in 1 thread* (I think more threads are added when you hit
    blocking I/O). You either need to set GOMAXPROCS or call
    runtime.GOMAXPROCS(threadcount). The preferred way is to use the
    environment variable. When you do that you should find your code running
    across multiple cores.

    Another note, go-routines are cheap and they do not map 1:1 to OS threads,
    in fact they are multiplexed on top of OS threads. Feel free to run lots
    of them.

    I wrote a Mandelbrot viewer a year or so ago in order to test out Go's
    concurrency. I just put it up on github
    (https://github.com/jonhanks/GoSDLFractal). The code creates a go-routine
    per scan line and allows the go-scheduler to figure out how that maps to OS
    threads. I have run it on OS X and Linux with Go 1 and 1.1. It can keep
    all of the cores busy when it recomputes the entire screen.

    It is one of my first Go projects, and so it is not necessarily the best
    example, but I don't know when I am going back to work on it in the nearish
    future so I thought I'd put it up.

    * See Rob Pike's talk concurrency is not parallelism
    http://blog.golang.org/concurrency-is-not-parallelism. Your code is
    currently concurrent, but not running in parallel (as far as I can see in a
    quick look through). The bright side of this, is that if you get the
    concurrency figured out, adding parallelism will be easier and safer.
    On Saturday, November 9, 2013 9:14:50 AM UTC-8, Nils wrote:

    I recently tried out Go and decided to write a small program which
    visualises the Mandelbrot set. I wanted to try out Go's complex number
    library as well as Go's concurrency support. Now I know that the proper way
    to do this would be to calculate everything on the GPU using a shader
    program or something like CUDA, it was merely an experiment to try out Go.
    The app itself is very easy to use, press f to go to the next iteration, b
    to go back and 1,2,4 and 8 to choose the number of threads calculating the
    mandelbrot set. On my Macbook Air it always takes at least 50ms to 200ms
    for more iterations. I think these numbers are already quite bad, there is
    however no (noticeable) difference if I use 1,2 or 4 threads! I think the
    CPU on my Macbook Air supports two hardware threads and two virtual ones. I
    also tried to profile it only to learn that the profiler does not support
    multiple threads on Mac OS right now. I will probably install Linux
    sometimes, but until then I wonder if some of the experienced Go developers
    can tell me why it is so slow. Code is here:
    https://github.com/nightlifelover/GoMandelbrot
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nils at Nov 10, 2013 at 4:24 pm
    Thanks for the nice answers :) I made the app go gettable, you can now just
    type go get github.com/nightlifelover/GoMandelbrot . Also it was running on
    one OS thread because I did not set GOMAXPROCS. I fixed that by adding runtime.GOMAXPROCS(runtime.NumCPU()
    * 2) and now it is faster when using more than one go routine, I think
    however it is still rather slow and could be improved. I guess I need to
    get the profiler running somehow.

    Jonathan: I also had a quick look at your implementation, but I could not
    get it working because I could not get the SDL bindings work on my Mac.

    On Saturday, November 9, 2013 9:07:17 PM UTC+1, jonathan...@gmail.com wrote:

    Nils,

    Are you setting the GOMAXPROCS environment variable? By default go will
    run everything in 1 thread* (I think more threads are added when you hit
    blocking I/O). You either need to set GOMAXPROCS or call
    runtime.GOMAXPROCS(threadcount). The preferred way is to use the
    environment variable. When you do that you should find your code running
    across multiple cores.

    Another note, go-routines are cheap and they do not map 1:1 to OS threads,
    in fact they are multiplexed on top of OS threads. Feel free to run lots
    of them.

    I wrote a Mandelbrot viewer a year or so ago in order to test out Go's
    concurrency. I just put it up on github (
    https://github.com/jonhanks/GoSDLFractal). The code creates a go-routine
    per scan line and allows the go-scheduler to figure out how that maps to OS
    threads. I have run it on OS X and Linux with Go 1 and 1.1. It can keep
    all of the cores busy when it recomputes the entire screen.

    It is one of my first Go projects, and so it is not necessarily the best
    example, but I don't know when I am going back to work on it in the nearish
    future so I thought I'd put it up.

    * See Rob Pike's talk concurrency is not parallelism
    http://blog.golang.org/concurrency-is-not-parallelism. Your code is
    currently concurrent, but not running in parallel (as far as I can see in a
    quick look through). The bright side of this, is that if you get the
    concurrency figured out, adding parallelism will be easier and safer.
    On Saturday, November 9, 2013 9:14:50 AM UTC-8, Nils wrote:

    I recently tried out Go and decided to write a small program which
    visualises the Mandelbrot set. I wanted to try out Go's complex number
    library as well as Go's concurrency support. Now I know that the proper way
    to do this would be to calculate everything on the GPU using a shader
    program or something like CUDA, it was merely an experiment to try out Go.
    The app itself is very easy to use, press f to go to the next iteration, b
    to go back and 1,2,4 and 8 to choose the number of threads calculating the
    mandelbrot set. On my Macbook Air it always takes at least 50ms to 200ms
    for more iterations. I think these numbers are already quite bad, there is
    however no (noticeable) difference if I use 1,2 or 4 threads! I think the
    CPU on my Macbook Air supports two hardware threads and two virtual ones. I
    also tried to profile it only to learn that the profiler does not support
    multiple threads on Mac OS right now. I will probably install Linux
    sometimes, but until then I wonder if some of the experienced Go developers
    can tell me why it is so slow. Code is here:
    https://github.com/nightlifelover/GoMandelbrot
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Carlos Castillo at Nov 11, 2013 at 12:39 pm
    If you are not averse to binary-patching your kernel (or how to go through
    the recovery procedure should something go wrong), you can use Russ Cox's
    fix for osx. It is described in detail
    at http://research.swtch.com/macpprof, and
    http://godoc.org/code.google.com/p/rsc/cmd/pprof_mac_fix.

    I am running it currently on my Mavericks box, and previously when it was a
    Lion box. Noticed no problems, except the unfortunate accuracy of my
    profiles ;-)
    On Sunday, November 10, 2013 8:24:15 AM UTC-8, Nils wrote:

    Thanks for the nice answers :) I made the app go gettable, you can now
    just type go get github.com/nightlifelover/GoMandelbrot . Also it was
    running on one OS thread because I did not set GOMAXPROCS. I fixed that by
    adding runtime.GOMAXPROCS(runtime.NumCPU() * 2) and now it is faster
    when using more than one go routine, I think however it is still rather
    slow and could be improved. I guess I need to get the profiler running
    somehow.

    Jonathan: I also had a quick look at your implementation, but I could not
    get it working because I could not get the SDL bindings work on my Mac.


    On Saturday, November 9, 2013 9:07:17 PM UTC+1, jonathan...@gmail.comwrote:
    Nils,

    Are you setting the GOMAXPROCS environment variable? By default go will
    run everything in 1 thread* (I think more threads are added when you hit
    blocking I/O). You either need to set GOMAXPROCS or call
    runtime.GOMAXPROCS(threadcount). The preferred way is to use the
    environment variable. When you do that you should find your code running
    across multiple cores.

    Another note, go-routines are cheap and they do not map 1:1 to OS
    threads, in fact they are multiplexed on top of OS threads. Feel free to
    run lots of them.

    I wrote a Mandelbrot viewer a year or so ago in order to test out Go's
    concurrency. I just put it up on github (
    https://github.com/jonhanks/GoSDLFractal). The code creates a
    go-routine per scan line and allows the go-scheduler to figure out how that
    maps to OS threads. I have run it on OS X and Linux with Go 1 and 1.1. It
    can keep all of the cores busy when it recomputes the entire screen.

    It is one of my first Go projects, and so it is not necessarily the best
    example, but I don't know when I am going back to work on it in the nearish
    future so I thought I'd put it up.

    * See Rob Pike's talk concurrency is not parallelism
    http://blog.golang.org/concurrency-is-not-parallelism. Your code is
    currently concurrent, but not running in parallel (as far as I can see in a
    quick look through). The bright side of this, is that if you get the
    concurrency figured out, adding parallelism will be easier and safer.
    On Saturday, November 9, 2013 9:14:50 AM UTC-8, Nils wrote:

    I recently tried out Go and decided to write a small program which
    visualises the Mandelbrot set. I wanted to try out Go's complex number
    library as well as Go's concurrency support. Now I know that the proper way
    to do this would be to calculate everything on the GPU using a shader
    program or something like CUDA, it was merely an experiment to try out Go.
    The app itself is very easy to use, press f to go to the next iteration, b
    to go back and 1,2,4 and 8 to choose the number of threads calculating the
    mandelbrot set. On my Macbook Air it always takes at least 50ms to 200ms
    for more iterations. I think these numbers are already quite bad, there is
    however no (noticeable) difference if I use 1,2 or 4 threads! I think the
    CPU on my Macbook Air supports two hardware threads and two virtual ones. I
    also tried to profile it only to learn that the profiler does not support
    multiple threads on Mac OS right now. I will probably install Linux
    sometimes, but until then I wonder if some of the experienced Go developers
    can tell me why it is so slow. Code is here:
    https://github.com/nightlifelover/GoMandelbrot
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Carlos Castillo at Nov 11, 2013 at 4:27 pm
    Some things to consider:

        1. Your program spends a lot of time doing "UI stuff" that will muddy up
        your profiles. This is assuming that you want to profile just your
        mandelbrot code.
           - It waits for user input; Instead you might want to run some
           input-less benchmark scenario when profiling
           - It has a hideously slow screen update routine (a GL_POINT for each
           pixel using GL immediate mode).
              - As a side note: cgo calls impose a few overheads of their own,
              so you should be minimizing the number of calls to C functions in your code
              wherever performance is important.
           - It attempts to limit output to 60fps, which during profiling, makes
           no sense.
           - I suggest you either make a profiling mode, or a gotest benchmark
           where no screen output is performed, and the algorithm can runs with as
           little interruption for a sufficiently large number of intervals
        2. github.com/andrebq/gas is broken on mac, you've bugged the maintainer
        about it, as have I, but you still might want to warn people about it in
        your README
        3. Your package needs the "DejaVuSansMono.ttf" font, installed to a
        "you" specific location; since your code was already dependent on (a
        working) gas, you could copy it to your repo, and use gas to load it.
        4. You might want to make the number of threads controllable through a
        command-line flag, instead of being fixed to runtime.NumCPU*2. This way you
        get the default you want, but it's still easy to change on a run-by-run
        basis, in case you want to run/profile a limited-thread case.
        5. Your code has a race (as detected by the race detector: go build
        -race), although not critical to correctness or speed, you should probably
        fix it.
    On Sunday, November 10, 2013 8:24:15 AM UTC-8, Nils wrote:

    Thanks for the nice answers :) I made the app go gettable, you can now
    just type go get github.com/nightlifelover/GoMandelbrot . Also it was
    running on one OS thread because I did not set GOMAXPROCS. I fixed that by
    adding runtime.GOMAXPROCS(runtime.NumCPU() * 2) and now it is faster
    when using more than one go routine, I think however it is still rather
    slow and could be improved. I guess I need to get the profiler running
    somehow.

    Jonathan: I also had a quick look at your implementation, but I could not
    get it working because I could not get the SDL bindings work on my Mac.


    On Saturday, November 9, 2013 9:07:17 PM UTC+1, jonathan...@gmail.comwrote:
    Nils,

    Are you setting the GOMAXPROCS environment variable? By default go will
    run everything in 1 thread* (I think more threads are added when you hit
    blocking I/O). You either need to set GOMAXPROCS or call
    runtime.GOMAXPROCS(threadcount). The preferred way is to use the
    environment variable. When you do that you should find your code running
    across multiple cores.

    Another note, go-routines are cheap and they do not map 1:1 to OS
    threads, in fact they are multiplexed on top of OS threads. Feel free to
    run lots of them.

    I wrote a Mandelbrot viewer a year or so ago in order to test out Go's
    concurrency. I just put it up on github (
    https://github.com/jonhanks/GoSDLFractal). The code creates a
    go-routine per scan line and allows the go-scheduler to figure out how that
    maps to OS threads. I have run it on OS X and Linux with Go 1 and 1.1. It
    can keep all of the cores busy when it recomputes the entire screen.

    It is one of my first Go projects, and so it is not necessarily the best
    example, but I don't know when I am going back to work on it in the nearish
    future so I thought I'd put it up.

    * See Rob Pike's talk concurrency is not parallelism
    http://blog.golang.org/concurrency-is-not-parallelism. Your code is
    currently concurrent, but not running in parallel (as far as I can see in a
    quick look through). The bright side of this, is that if you get the
    concurrency figured out, adding parallelism will be easier and safer.
    On Saturday, November 9, 2013 9:14:50 AM UTC-8, Nils wrote:

    I recently tried out Go and decided to write a small program which
    visualises the Mandelbrot set. I wanted to try out Go's complex number
    library as well as Go's concurrency support. Now I know that the proper way
    to do this would be to calculate everything on the GPU using a shader
    program or something like CUDA, it was merely an experiment to try out Go.
    The app itself is very easy to use, press f to go to the next iteration, b
    to go back and 1,2,4 and 8 to choose the number of threads calculating the
    mandelbrot set. On my Macbook Air it always takes at least 50ms to 200ms
    for more iterations. I think these numbers are already quite bad, there is
    however no (noticeable) difference if I use 1,2 or 4 threads! I think the
    CPU on my Macbook Air supports two hardware threads and two virtual ones. I
    also tried to profile it only to learn that the profiler does not support
    multiple threads on Mac OS right now. I will probably install Linux
    sometimes, but until then I wonder if some of the experienced Go developers
    can tell me why it is so slow. Code is here:
    https://github.com/nightlifelover/GoMandelbrot
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 9, '13 at 5:14p
activeNov 11, '13 at 4:27p
posts6
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase