Hi Rolf,

Thanks for having a look at this. Goes to show that having a second look helps. 
I wasn't aware of the 100x loop, totally overlooked that, DOH!

Anyway, your clarification helps a lot, so thanks for that!

Regards, Roy

From: Rolf Bjarne Kvinge [mailto:[email protected]]
Sent: woensdag 15 februari 2012 13:41
To: Roy Cornelissen
Cc: [email protected]
Subject: Re: [MonoTouch] Why is the MonoTouch version of this Mandelbrot Set 
test 2.8 times slower?

Hi,

I tried your projects, and got somewhat different results (on an iPad2).

Objective-C implementation: 0,296s
MonoTouch (release mode): 0,677s
MonoTouch (release mode, with LLVM enabled): 0,397

So just MonoTouch release mode is 2.3x times slower, but once you enable LLVM, 
this goes down to 1.34x slower.

I also noticed that BitmapContext.FillRect is called a lot (39635 times), so I 
commented it out and now I get these timings:
Objective-C implementation: 0,224s
MonoTouch (LLVM enabled): 0,293s

So just calling FillRect 39635 times takes 0,072s in ObjC and 0,104s with 
MonoTouch - the discrepancy is due to the fact that the MonoTouch version 
obviously has to do more work (it has to do a managed-to-native transition (and 
back again)). So now MonoTouch is 1.31x slower.

The point is that LLVM mode is exactly for this kind of cpu intensitive tasks, 
since our jit doesn't generate as optimized code as the LLVM one can.

Now I started looking a bit deeper, and realized that the loop in 
IsInMandelbrotSet loops 100 times in the MonoTouch version and only 50 times in 
the ObjC version. Redoing the tests in MonoTouch, but this time only looping 50 
times, I get this:

MonoTouch (LLVM enabled): 0,290s.
Yes, that's correct. The MonoTouch (with LLVM) version is actually 1% faster 
than the ObjectiveC version with identical code.

And as shown this difference can probably be increased (by not calling FillRect 
40k times, but perhaps manually create the bitmap in managed memory and then 
draw the bitmap with one call - this change would likely benefit both 
implementations, but it would benefit MonoTouch most).

I hope this helps :)

Rolf

On Wed, Feb 15, 2012 at 10:14 AM, RoyCornelissen 
<[email protected]<mailto:[email protected]>> wrote:
> Hi,
>
> Just as a little exercise I decided to try out a Mandelbrot test in
> MonoTouch just to have a look at performance. I took this Objective-C
> implementation  https://github.com/ddeville/Mandelbrot-set-on-iPhone on
> GitHub  as a basis and ported the implementation of the view 1-to-1 to
> MonoTouch. Because of some differences in API not all of the code is 100%
> the same, and I'm no CoreGraphics expert, but as far as I know this looks
> OK. The MonoTouch implementation can be found here
> http://dl.dropbox.com/u/1135505/MonobrotSet.zip
>
> Now when I run this on my iPhone, the MonoTouch version is 2.8 times slower
> than the Objective-C version, specifically the part where the Mandelbrot Set
> is drawn in the bitmap. Objective-C takes ~0.99 seconds, MonoTouch ~2.8
> seconds.
>
> Can anyone help explain where the overhead is coming from? Is there anything
> I could have done to make this faster given the reference implementation in
> Objective-C? I'm not looking for a faster Mandelbrot algorithm but merely
> trying to explain what is making the big difference. Or did I make a mistake
> in translating the Objective-C code to MonoTouch?
>
> Here's the C# code that does the work, I tried to stay as close as possible
> to the Objective-C implementation of the view
> https://github.com/ddeville/Mandelbrot-set-on-iPhone/blob/master/Classes/MandelbrotView.m
> (link)
>
>        [Register("MandelbrotView")]
>        public class MandelbrotView: UIView
>        {
>                private const int MANDELBROT_STEPS = 50;
>
>                public MandelbrotView ()
>                {
>                        Initialize();
>                }
>
>                public MandelbrotView(IntPtr handle): base (handle)
>                {
>                        Initialize();
>                }
>
>                public override void Draw (System.Drawing.RectangleF rect)
>                {
>                        DateTime reference = DateTime.Now;
>
>                        // get an image representation of the bitmap context
>                        var image = _bitmapContext.ToImage();
>
>                        // draw the image in the current context
>                        var context = UIGraphics.GetCurrentContext();
>                        context.DrawImage(rect, image);
>
>                        // release the image
>                        image.Dispose();
>
>                        Console.WriteLine("draw rect duration = {0}", 
> (DateTime.Now -
> reference).TotalMilliseconds / 1000);
>                }
>
>                private CGBitmapContext _bitmapContext;
>
>                private void Initialize ()
>                {
>                        Console.WriteLine("MonoTouch Mandelbrot 
> implementation");
>                        var reference = DateTime.Now;
>
>                        // instantiate the bitmap context
>                        _bitmapContext = CreateCustomBitmapContextWithSize(new 
> SizeF(480.0f,
> 320.0f));
>
>                        Console.WriteLine("bitmap context creation duration = 
> {0}", (DateTime.Now
> - reference).TotalMilliseconds / 1000);
>                        reference = DateTime.Now;
>
>                        // draw the Mandelbrot Set
>                        var center =  new PointF(this.Center.Y, this.Center.X);
>                        DrawMandelbrot(center, 1);
>
>                        Console.WriteLine("drawing mandelbrot in bitmap 
> duration = {0}",
> (DateTime.Now - reference).TotalMilliseconds / 1000);
>                }
>
>                private CGBitmapContext 
> CreateCustomBitmapContextWithSize(SizeF size)
>                {
>                        CGBitmapContext context = null ;
>
>                        var bitmapBytesPerRow = (size.Width * 4) ;
>                        bitmapBytesPerRow += (16 - bitmapBytesPerRow%16)%16 ;
>
>                        var bitmapByteCount = (bitmapBytesPerRow * 
> size.Height) ;
>
>                        CGColorSpace colorSpace = 
> CGColorSpace.CreateDeviceRGB();
>
>                        var bitmapData = new byte[(int) bitmapByteCount];
>
>                        context = new CGBitmapContext(bitmapData, (int) 
> size.Width, (int)
> size.Height, 8, (int) bitmapBytesPerRow, colorSpace,
> CGBitmapFlags.PremultipliedLast);
>
>                        if (context == null)
>                        {
>                                bitmapData = null;
>                                Console.WriteLine("Context not created!");
>                                return null;
>                        }
>
>                        return context;
>                }
>
>
>                private void DrawMandelbrot(PointF center, float zoom)
>                {
>                        _bitmapContext.SetAllowsAntialiasing(false);
>                        _bitmapContext.SetRGBFillColor(0.0f, 0.0f, 0.0f, 1.0f);
>
>                        float re;
>                        float im;
>
>                        // mapping the bounding box to pixels
>
>                        // zoom 1 has to be between -2 and 1 and -1 to 1
>                        // any additional zoom divides these by the zoom
>
>                        // loop through every pixel of the frame...
>                        for (int i = 0 ; i < 480 ; i++)
>                        {
>                                for (int j = 0 ; j < 320 ; j++)
>                                {
>                                        re = (((float)i - 1.33f * 
> center.X)/160) ;      // -2 to 1      -       screen width  =
> 480
>                                        im = (((float)j - 1.00f * 
> center.Y)/160) ;      // -1 to 1      -       screen height =
> 320
>
>                                        re /= zoom ;
>                                        im /= zoom ;
>
>                                        if (IsInMandelbrotSet(re, im))
>                                        {
>                                                _bitmapContext.FillRect(new 
> RectangleF(i, j, 1.0f, 1.0f));
>                                        }
>                                }
>                        }
>                }
>
>                private bool IsInMandelbrotSet(float re, float im)
>                {
>                        float x = 0 ;   float nx ;
>                        float y = 0 ;   float ny ;
>                        bool fl = true;
>                        for(int i = 0 ; i < MANDELBROT_STEPS ; i++)
>                        {
>                                // We calculate the real part of the sequence
>                                nx = x*x - y*y + re ;
>                                // We calculate the imaginary part of the 
> sequence
>                                ny = 2*x*y + im ;
>                                // We compute the magnitude at each step
>                                // We check if it's greater than 2
>                                if((nx*nx + ny*ny) > 4)
>                                {
>                                        fl = false ;
>                                        break ;
>                                }
>                                x = nx ;
>                                y = ny ;
>                        }
>
>                        return fl ;
>                }
>        }
>
> Thanks, Roy
>
> --
> View this message in context: 
> http://monotouch.2284126.n4.nabble.com/Why-is-the-MonoTouch-version-of-this-Mandelbrot-Set-test-2-8-times-slower-tp4389869p4389869.html
> Sent from the MonoTouch mailing list archive at Nabble.com.
> _______________________________________________
> MonoTouch mailing list
> [email protected]<mailto:[email protected]>
> http://lists.ximian.com/mailman/listinfo/monotouch

Op dit e-mailbericht is de disclaimer van Info Support van toepassing, zie 
http://www.infosupport.com/disclaimer

[cid:disclaimer3d6c.jpg]<http://www.infosupport.com/>

<<inline: disclaimer3d6c.jpg>>

_______________________________________________
MonoTouch mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/monotouch

Reply via email to