[Mono-dev] Faster

Elijah Taylor elijahtaylor at google.com
Thu Mar 24 14:13:48 EDT 2011


If it's worth anything, changing null checks to NREs would also severely
cripple Native Client support in Mono.  NREs rely on hardware signals if I'm
not mistaken, and we don't support that currently (and probably not for a
long time if ever) in NaCl.  We've actually had to rewrite bits of
application code that relied on this behavior instead of explicit null
checks.


On Thu, Mar 24, 2011 at 9:51 AM, Rodrigo Kumpera <kumpera at gmail.com> wrote:

> Mono uses zero cost exception handling, so setting up a try-catch handler
> has zero cost.
>
> That's the theory, but using try-catch blocks have a few undesirable
> implications to control-flow.
> The problem are variables that are used in the catch block, for example:
>
> int x;
> try {
>   x = 1;
>   MayThrow ();
>   x = 2;
>   MayThrow ();
>   x = 3;
> } catch (Exception) {
>   Console.WriteLine (x);
> }
>
> On the above code, when we reach the catch block, we can't statically know
> which assignment was the last to execute, so we have
> to make sure they all use the same storage - which is a very hard problem
> to solve.
>
> Mono's current JIT takes the easy solution which is to mark all those
> variables as volatile, which has the unfortunate effect of producing
> code outside the catch block that is quite worse than otherwise. So, EH has
> a very low overhead, but should not be used for those cases.
>
> Now onto the null check. Such a null check will exploit a cpu feature known
> as branch prediction, which guesses the outcome of the
> conditional jump. Since in the majority of the cases the value won't be
> null, the cpu can pretend the branch doesn't exist and keep executing
> as it was not taken. This means the null check costs virtually nothing on a
> modern cpu.
>
>
>
> On Thu, Mar 24, 2011 at 5:32 PM, Mikael Lyngvig <mikael at lyngvig.org>wrote:
>
>> Hi,
>>
>> I'm not an expert on the JIT compiler and such, but I do know that in
>> virtually all programming languages that support exception handling, the
>> cost of a null-check is infinitesimal compared to the cost of setting up
>> an exception handler.  On many systems, setting up a try-catch handler
>> costs something like 200 instructions whereas the null check only costs
>> one or two instructions.
>>
>> Cheers,
>> Mikael
>>
>> Den 24-03-2011 17:06, Steve Bjorg skrev:
>> > Is the cost of the if-null check greater than setting up an exception
>> catch handler?
>> >
>> > - Steve
>> >
>> > ---------------------------------
>> > Steve G. Bjorg
>> > MindTouch
>> > San Diego, CA
>> >
>> > 619.795.8459 office
>> > 425.891.5913 mobile
>> > http://twitter.com/bjorg
>> >
>> > On Mar 24, 2011, at 9:00 AM, Miguel de Icaza wrote:
>> >
>> >> Hello guys,
>> >>
>> >> Today in the shower I had an idea that I believe we could use to
>> >> improve the performance of our class library code.
>> >>
>> >> Plenty of our class library code has code like this:
>> >>
>> >> void Foo (Something x)
>> >> {
>> >>     if (x == null)
>> >>         throw new ArgumentNullException ("x");
>> >>     x.DoSomething ();
>> >>     x.AndThenMore ();
>> >> }
>> >>
>> >> Arguably, if this could be inlined, and the JIT could prove that x is
>> >> not null, we would skip the first test, for example:
>> >>
>> >> Foo (new Something ());
>> >>
>> >> But this is the exception, in general, the JIT would not be able to
>> >> know this kind of information for even trivial uses like:
>> >>
>> >> Foo (Bar.GetSomething ());
>> >>
>> >> Rendering the optimization not very effective.
>> >>
>> >> But what if we changed our code in Foo across our class libraries to
>> >> do this instead:
>> >>
>> >> void Foo (Something x)
>> >> {
>> >>     try {
>> >>         x.DoSomething ();
>> >>     } catch (NullReferenceException e){
>> >>         if (x == null)
>> >>              throw new ArgumentNullException ("x");
>> >>         else
>> >>               throw;
>> >>     }
>> >>     x.AndThenMore ();
>> >> }
>> >>
>> >> This has the advantage that the test for the value of "x" being null
>> >> is delayed until we actually need it.    The downside of course is
>> >> that DoSomething could actually take other forms and might end up
>> >> running code that we do not need before it touches x, for example,
>> >> this would be a problem:
>> >>
>> >> // We should never add null values.
>> >> void AddToCache (Something x)
>> >> {
>> >>     cache.Add (x);
>> >> }
>> >>
>> >> void Foo (Something x)
>> >> {
>> >>       if (x == null)
>> >>           throw new ArgumentNullException ("x");
>> >>       AddToCache (x);
>> >> }
>> >>
>> >> If we rewrite the above code, we would end up with a bug like the one
>> >> I described.
>> >>
>> >> Miguel
>> >> _______________________________________________
>> >> Mono-devel-list mailing list
>> >> Mono-devel-list at lists.ximian.com
>> >> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>> > _______________________________________________
>> > Mono-devel-list mailing list
>> > Mono-devel-list at lists.ximian.com
>> > http://lists.ximian.com/mailman/listinfo/mono-devel-list
>> >
>>
>> _______________________________________________
>> Mono-devel-list mailing list
>> Mono-devel-list at lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>
>
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20110324/76aee697/attachment-0001.html 


More information about the Mono-devel-list mailing list