[Patch, fortran] PR24518 and PR24520 - Improvements to MOD and DOT_PRODUCT
Paul Thomas
paulthomas2@wanadoo.fr
Sat Nov 12 10:19:00 GMT 2005
:REVIEWPATCH:
Janne and Tobi,
Thank you for your comments. For the reasons that I outline below, I am
withdrawing this patch for repairs. I will resubmit when I am satisfied
that I have satisfactory solutions for the optimal switching between
library and inline.
>BTW, does BLAS do anything fancy for dot product that might help for
>big vectors? I mean, is it worth thinking about inlining only for
>small vectors? What happpens when the vectors won't fit into cache?
>I'm not saying this as a criticism of your patch, just idle
>wondering..
>
I have found circumstances where the library and inline DOT_PRODUCT
execution times cross over at lengths ~32.
The timing test that I supplied with the patch is a complete aberration
on my part, as a quick examination will reveal, and the results should
be ignored completely.
Please find attached a test which is more "realistic" (ie. correct):
With -O3 -ffast-math, I obtain:
DOT_PRODUCT test library inline
array length time(ns) time(ns)
-ve stride (+ve stride)
4 57.90 34.20 (22.00)
8 58.70 34.90 (22.20)
16 94.70 76.60 (67.20)
32 140.40 133.30 (112.50)
64 230.60 247.20 (203.70)
128 412.80 473.50 (385.40)
256 775.10 927.20 (748.00)
512 1500.80 1833.40 (1472.40)
1024 2949.30 3645.70 (2921.10)
The time for the library function does not depend on the stride of the
arguments of DOT_PRODUCT. What I learn from this is:
(i) Lengths 4 and 8 are too fast for the timer resolution.
(ii) There is an overhead of ~25ns for the library function call.
(iii) With a positive stride, this difference between the library and
the inline is present for any vector length.
(iv) The more complicated scalarizer index arithmetic makes the inline
slower per element, so that the advantage is lost between vector lengths
of 32 and 64.
-ve stride:
{
if (S.7 > D.603) goto L.8; else (void) 0;
val.6 = val.6 + xin[D.604 - S.7 + -1] * yin[D.602 - S.7 + -1];
S.7 = S.7 + 1;
}
+ve stride
{
if (S.7 > (int4) m) goto L.8; else (void) 0;
val.6 = val.6 + xin[NON_LVALUE_EXPR <S.7> + -1] * yin[NON_LVALUE_EXPR
<S.7> + -1];
S.7 = S.7 + 1;
}
(Perhaps this is an indication for a bit of work on the scalarizer? ie.
to copy the library function by setting up a pointer and incrementing it
as in the +ve stride?)
The execution time of the Polyhedron test f90/induct.f90 drops from 392s
to 67s (versus 141s for ifc with -O3) with the patch, so it is still
worth having! Dot products of 3 vectors really win out with the inline
version.
I need to think how to implement the cross-over from inline to library.
Does anybody have a suggestion as to how best to do this? Assume that
all systems will have a similar cross-over array length?
>>New: Sets result to zero if the abs(result) is larger that abs(arg2).
>>
>
>I'm not entirely comfortable with this. This might give the user a
>false sense of security. At least a huge value is obviously wrong.
>
>
OK, noted. Given Tobi's remark about the rounding errors, I clearly
need to think about this. If I remove the large quotient safety net and
the casting, mod is a lot faster. On the other hand, the builtin fmod
does keep going, essentially, to infinity by comparison with either the
original or the new MOD. Perhaps, again, we need to changeover from
inline to library at a certain value of the quotient?
Cheers
Paul T
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: dot_demo2.f90
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20051112/01c02c0f/attachment.f90>
More information about the Fortran
mailing list