Submitted by Washu (not verified) on Thu, 2007-10-11 07:18.
While I haven't posted part 5 (and I really should), I though I would briefly mention it here.
One of the things I investigated (and will eventually get around to writing up and posting) is whether reordering of code could improve the JIT produced assembly. For instance, as you may note in the assembly dumps, the vector dot product has 6 bounds checks to ensure the integrity of the arrays (i.e. they are at least the proper size). However, one might note that simply testing for the largest size would save 4 checks. But, if one adds the constraint that the exception produced will tell the exact index that failed, then we can't eliminate the other 4 (this constraint doesn't exist, and a simple case of static analysis would eliminate the redundant checks...).
By reordering the vector code such that the largest index of each array is accessed first, one might assume that one could assist ngen or the JIT during its static analysis in removing the redundant checks. For example:
However this will not generate the expected outcome, and instead all 6 checks will remain, just in reverse order, which is a pitty, but future work (.net 3.5 for instance) may fix these short comings.
I should note that I specifically wrote my test code to ensure that the JIT could not optimize out the exception checks, as they were important to the overall test framework. Simple tests ,such as calling to that function and passing a properly sized array, will allow for static analysis to eliminate the exception checks entirely. However when one is dealing with a realistically complex code base static analysis cannot make the assumptions, in the time allocated for it, that it can with simplistic examples. Hence the code was designed to explicitly force trivial static analysis to fail while allowing for more complex methods to succeed. One can see the more complex methods in the ways in which it optimized returning a float vs setting an out float parameter.
Performance implications of .Net JITted code
While I haven't posted part 5 (and I really should), I though I would briefly mention it here.
One of the things I investigated (and will eventually get around to writing up and posting) is whether reordering of code could improve the JIT produced assembly. For instance, as you may note in the assembly dumps, the vector dot product has 6 bounds checks to ensure the integrity of the arrays (i.e. they are at least the proper size). However, one might note that simply testing for the largest size would save 4 checks. But, if one adds the constraint that the exception produced will tell the exact index that failed, then we can't eliminate the other 4 (this constraint doesn't exist, and a simple case of static analysis would eliminate the redundant checks...).
By reordering the vector code such that the largest index of each array is accessed first, one might assume that one could assist ngen or the JIT during its static analysis in removing the redundant checks. For example:
result = x[3] * y[3] + x[2] * y[2] + x[1] * y[1] + x[0] * y[0];
}
However this will not generate the expected outcome, and instead all 6 checks will remain, just in reverse order, which is a pitty, but future work (.net 3.5 for instance) may fix these short comings.
I should note that I specifically wrote my test code to ensure that the JIT could not optimize out the exception checks, as they were important to the overall test framework. Simple tests ,such as calling to that function and passing a properly sized array, will allow for static analysis to eliminate the exception checks entirely. However when one is dealing with a realistically complex code base static analysis cannot make the assumptions, in the time allocated for it, that it can with simplistic examples. Hence the code was designed to explicitly force trivial static analysis to fail while allowing for more complex methods to succeed. One can see the more complex methods in the ways in which it optimized returning a
floatvs setting anout floatparameter.