Thanks, Zoltan pointed out that the performance under LLVM is pretty good, so I 
probably did not have LLVM enabled.  Indeed I checked and found that to be the 
case (my bad).  As for the pattern you mention, aware that mono is able to 
avoid checks in that scenario.  

More often then not, though, I am dealing with structures that use double[] 
with allocations > the span of interest (as the series grow in size).  So I 
usually have to rely on a variable that indicates size rather than 
array.Length.   I could have used in this test though.

It would be nice (and seemingly would be straightforward) if the JIT was able 
to recognize:

the len variable is invariant / locally scoped with respect to the loop
can have 2 code paths:
one for if the condition will be within bounds (can avoid bounds checking)
one for if the condition is either not in bounds or cannot be determined to be 
invariant (hence should do the normal bounds checking)

I suppose a crutch to work around this, playing to mono's jit would be:

for (int i = 0 ; i < array.Length ; i++)
{
        if (i < <length expression>)
                <do computation on array[i]>
        else
                break;
}

The cost of the extra condition might outweigh the benefit (I haven't studied 
the branch cycle times to know).    Better would be:

if (<length expression> <= array.Length AND invariant)
{
        for (int i = 0 ; i < <length expression> ; i++)
        {
                <do computation on array[i] without checks>
        }
}
else
{
        for (int i = 0 ; i < <length expression> ; i++)
        {
                <do computation on array[i] with checks>
        }
}

It is too bad that one cannot declare a primitive expression to be locally 
const in C#.  In java one can do something like:

        final int len = <some expression>
        for (int i = 0 ; i < len ; i++) ...

OR in C#

        const int len = <some expression>    (error if the expression refers to 
functions or variables)

With an explicit notion of invariance could simplify the decision for the JIT.


On Nov 20, 2011, at 11:38 AM, Konrad M. KruczyƄski wrote:

> Hi,
> 
> I'd like to add that you may gain something on MS JIT compiler using 
> for (int i = 0 ; i < x.Length ; i++)
> instead of
> for (int i = 0 ; i < len ; i++)
> 
> This may seem counter intuitive, however that's the scenario in which
> JIT eliminates array bound checking for the x array (however not for the
> second one) as arrays have constant length. I am not sure whether Mini
> recognizes that. I'm pretty sure that Hotspot is much smarter here ;)
> 
> As Zoltan wrote in the bug comments, enabling LLVM improves the results
> a lot. This is, I guess, due to much better register allocation in which
> domain Mini isn't too good - and probably other optimizations like
> better loop unrolling.
> 
> If I remember correctly, there once was a branch of LLVM with array
> bounds check elimination, is it still developed?
> 
> I am also curious which code patterns enable ABC elimination in Mini.
> 
> On Sun, 2011-11-20 at 08:01 -0500, Jonathan Shore wrote:
>> Here is a link to and entry in bugzilla with attached code.  I could
>> not send to the list:
>> 
>> 
>> http://bugzilla.xamarin.com/show_bug.cgi?id=2098
>> 
> 
> --
> Regards,
> Konrad
> 
> 

_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to