I've been tinkering with my fractal plotter again. One thing that annoyed me about it was the pauses when you zoomed in or out past a power of 2. I thought this was due to matrix operations until I did some profiling and discovered that it was actually dilation (both doubling and halving) of the "tiles" of graphical data to which squares are plotted and which themselves are painted to the screen.
This is work that can quite easily be done on the GPU, without even having to resort to pixel shaders, by using the ability to render to a texture. Here is the result and here is the source. In order to do this I moved all the tiles to video memory (default pool instead of managed pool) and used ColorFill() to actually plot blocks instead of locking and writing directly to textures. All this adds up to much more CPU time available for fractal iterations.
Another change is that instead of an array of grids of tiles, I've switched to using a grid of "towers" each of which is itself a tile and can point to 4 other towers. This simplifies the code somewhat.
There is still some glitchiness when zooming but it is much less noticable now.
This reminds me of something I meant to write about here. When I originally converted my fractal program to use Direct3D, I figured that locking and unlocking textures was probably an expensive operation so rather than locking and unlocking every time I needed to plot a square, I kept them all locked most of the time and just unlocked them to paint. However, it turns out that this "optimization" was actually a terrible pessimization - now all the tiles were dirtied each frame and had to be copied from system memory to video memory for each paint, and because of the locking nothing else could happen during that time. I was able to get a big speed up by locking and unlocking around each plot operation - that caused only the parts of tiles that were actually plotted on to be dirtied. It just goes to show that when optimizing you do have to be careful to actually measure performance and see where the slow bits really are.
This is really amazing! I couldn't believe how fast it zooms even on very high dwell limit areas. I hope you continue to work on this.
Thanks, Luke! Yes, I'm continuing to improve it - the next things I want to do with it:
Arbitrary precision so you can zoom in as far as you like.
Extra algorithmic cleverness (SOI and possibly also periodicity analysis) to improve calculation times.
Client/server architecture so you can use other computers to speed up calculation.
Exploitation of symmetry.
A formula compiler.
A way to change the colours.
A way to generate videos.
[...] added arbitrary precision arithmetic to my Mandelbrot zoomer. Surprisingly, the difficult part wasn’t the arbitrary precision arithmetic itself, it was [...]