Re: -ffast-math algebraic optimizations on custom number types

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 27/08/2024 22:44, Kai Song wrote:
Thank you, David! That was very useful!

Glad to be of help!

I don't think expression templates are going to be able to cover everything. I have only played with them a little myself, not used them seriously, so I am no expert here. But I would expect you will hit limitations with them long before you get to global transformations - I think they will be a challenge as soon as there is more than one reasonable way to transform an expression. Still, I think they could be a cheap (in terms of your time as a developer) way to handle some common transforms, such as combinations of constants.

In my head, I have a vague notion of having two classes - Expression_Constant<Numeric n> and Expression_Variable, both inheriting from an Expression<> template using CRTP to provide compile-time polymorphism. Code can use an "if consteval" to determine whether a given Numeric is known to be a constant (and thus put it in an Expression_Constant<>) or not.

Combining Expression_Constant<> objects should be quite easy - just provide operator overloads. The real "fun" comes when you mix them with Expression_Variable's. You perhaps need some way to turn "x + y + z" into a single function call "add(x, y, z)" - then you can provide overloads for that function for different combinations of Constant and Variable, letting you combine Constant's even if they are not adjacent.

Of course, that depends on Numeric's operations being commutative and associative - you have to decide on that!

David



You said one thing very nicely:

>> you cannot expect to be able to lift floating-point specific parts from deep within
the gcc optimiser and re-use them for your own code here.

I confirm that this was it that I was expecting (or rather hoping :) ).

Given my pessimism drawn from the apparent misunderstanding in the communication prior, I have already started to re-implement those expression templates that are probably hidden deep within GCC.

Now as you and I discussed expression templates, my reluctance with those at first is their limitation on the complexity of DAG optimizations due to only permitting transformations that are possible via
meta programming (i.e., no global DAG transformations).
But that is then just a practical 20-80 rule where one has to make compromises.

Thank you for considering my question in detail and answering helpfully!

On Tue, Aug 27, 2024 at 10:26 AM David Brown <david.brown@xxxxxxxxxxxx <mailto:david.brown@xxxxxxxxxxxx>> wrote:

    I think expression templates are what you need here.

    The "-ffast-math" optimisations are very specific to floating point
    calculations, and are quite dependent on the underlying implementation
    of floating point.  Contrary to Segher's pessimism, "-ffast-math" is
    extremely useful and gives significantly better end results in
    situations where it is appropriate.  But like any floating point work,
    you need to understand the limitations and the suitability for the task
    at hand.

    I can't see how they could be of any use to you here, other than
    perhaps
    that the documentation for the flag might be an inspiration for the
    kind
    of re-arrangements you want to support.  As I understand it, it is the
    code you are writing that will do the re-arrangements - you cannot
    expect to be able to lift floating-point specific parts from deep
    within
    the gcc optimiser and re-use them for your own code here.

    You have to decide what re-arrangement rules you will accept for your
    Number type, and build up appropriate expression templates.  The rules
    you accept will depend entirely on what "Number" is.  If it represents
    ideal mathematical integers, then you get lots of possibilities.  If it
    represents fixed-size floating point numbers, then now re-arranging "(x
    + y) - x" into "y" can give a very different result.  Just like with
    "-ffast-math", such a re-arrangement is fine if you are equally happy
    with both results.

    David



    On 27/08/2024 00:04, Kai Song via Gcc-help wrote:
     > I would like to add an example so as to clarify what it is that I
    seek help
     > on:
     >
     > I have a custom implementation of a class called Number. Number has
     > overloaded operators that write down a program of all
    computations that
     > Number witnesses in an original program.
     > For example, when the original program reads (original code):
     > z=x-(-y);
     >
     > Then upon execution with type Number the following program will
    be produced
     > (generated code) as caused through stream buffers in Number:
     > tmp1 = -y;
     > z = x-tmp1;
     >
     > This generated code is inferior to as if the original code had been
     > "z=x+y;".
     > Using expression templates or hoping for excellent compiler
    optimization on
     > the "generated code", I could try to improve the performance of the
     > generated code.
     > But that means equal to re-inventing the wheel, because obviously the
     > compilers have exactly these algebraic optimization capabilities
    already
     > built in.
     > So I want to use these capabilities. This is what my request is
    all about.
     >
     > Certainly the compiler has algebraic expression optimization
    built in, so
     > what I now seek to find out is whether and how this can be leveraged
     > outside the rule-scope of native c++,
     > so as to improve the algebra of my original code. Of course I am
    aware that
     > this alters the original programs result entirely (as per the above
     > example) but this is precisely what I wish for.
     >
     > Kind regards
     >
     >
     >
     > In response to Segher:
     >
     > On Mon, Aug 26, 2024 at 7:19 PM Segher Boessenkool <
     > segher@xxxxxxxxxxxxxxxxxxx <mailto:segher@xxxxxxxxxxxxxxxxxxx>>
    wrote:
     >
     >> On Mon, Aug 26, 2024 at 06:00:21PM +0200, Kai Song via Gcc-help
    wrote:
     >>> I would like to learn more how GCC implements algebraic
    optimization
     >>> heuristic such as given in -ffast-math .
     >>
     >> Thank you for responding. Yet I cannot make sense of your
    response or
     > whether if how it relates to what I asked about.
     >
     >
     >> Oh dear.
     >>
     >>> In particular, I have a type Number that is used in a code
     >>
     >> -ffast-math means you are not dealing with numbers at all, but
    instead
     >> with quantities somewhat akin to numbers, and you don't give two
    hoots
     >> about what happens with them.
     >>
     >
     > Well if it was able to "deal" with anything akin to numbers, that
    would
     > imply I can tell it to treat a type as if it was a number.
     > Clearly however, that is not the case. So you may have meant
    something
     > else, which is impossible to identify then due to ambiguity.
     > This is unfortunate because I deeply care. So if you indeed mean that
     > fastmath can be applied to anything akin to numbers,
     > I am looking forward to how I can use the compilers abilities in that
     > regard to transform algebraic expressions with custom types.
     >
     >
     >>
     >> It replaces floating point expressions by other expressions that are
     >> at best vaguely related, and almost always compute a very different
     >> result.
     >>
     >
     > Yes, so here it is besides the question; because my custom type
    Number,
     > which is the single point of interest in the communication, is not a
     > floating point type.
     >
     >
     >>
     >> If you do not care about your numbers at all, and (against better
     >> judgement) prefer more speed over all quality, you can use
    -ffast-math.
     >>
     >
     > Well apparently I cannot, as per my question, since the algebraic
     > expressions are involving my custom class Number.
     >
     >
     >> Or, you can admit you think arithmetic is magic.  It is fine to use
     >> then, too.
     >>
     >
     > I am a mathematician. I do not know nor wonder what you seek to say.
     > I do care that arithmetic expressions are concise and equivalent.
     > For instance, I like when "z=x-(-y);" is replaced by "z=x+y;"
    where x and y
     > may be of type Number.
     >
     >
     >> Segher
     >>
     >





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux