From: Richard Guenther <richard.guenther@gmail.com>
To: Xinliang David Li <davidxl@google.com>
Cc: Sriraman Tallam <tmsriram@google.com>, gcc@gcc.gnu.org
Subject: Re: Function Multiversioning Usability.
Date: Wed, 17 Aug 2011 15:12:00 -0000 [thread overview]
Message-ID: <CAFiYyc2=GhrA+pE46ZTqkQkD+PqETM+1Ht5Aj3CVLzsqXm7uWA@mail.gmail.com> (raw)
In-Reply-To: <CAAkRFZLLaXgHs6LP3PfbN4KgT_spL3t4So8q9Yy_etELF=fF9w@mail.gmail.com>
On Wed, Aug 17, 2011 at 4:52 PM, Xinliang David Li <davidxl@google.com> wrote:
> The gist of previous discussion is to use function overloading instead
> of exposing underlying implementation such as builtin_dispatch to the
> user. This new refined proposal has not changed in that, but is more
> elaborate on various use cases which has been carefully thought out.
> Please be specific on which part needs to improvement.
See below ...
> Thanks,
>
> David
>
> On Wed, Aug 17, 2011 at 12:29 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Tue, Aug 16, 2011 at 10:37 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>> Hi,
>>>
>>> I am working on supporting function multi-versioning in GCC and here
>>> is a write-up on its usability.
>>>
>>> Multiversioning Usability
>>> ====================
>>>
>>> For a simple motivating example,
>>>
>>> int
>>> find_popcount(unsigned int i)
>>> {
>>> return __builtin_popcount(i);
>>> }
>>>
>>> Currently, compiling this with -mpopcnt will result in the “popcnt”
>>> instruction being used and otherwise call a built-in generic
>>> implementation. It is desirable to have two versions of this function
>>> so that it can be run both on targets that support the popcnt insn and
>>> those that do not.
>>>
>>>
>>> * Case I - User Guided Versioning where only one function body is
>>> provided by the user.
>>>
>>> This case addresses a use where the user wants multi-versioning but
>>> provides only one function body. I want to add a new attribute called
>>> “mversion” which will be used like this:
>>>
>>> int __attribute__(mversion(“popcnt”))
>>> find_popcount(unsigned int i)
>>> {
>>> return __builtin_popcount(i);
>>> }
>>>
>>> With the attribute, the compiler should understand that it should
>>> generate two versions for this function. The user makes a call to this
>>> function like a regular call but the code generated would call the
>>> appropriate function at run-time based on a check to determine if that
>>> instruction is supported or not.
The example seems to be particularly ill-suited. Trying to 2nd guess you
here I think you want to direct the compiler to emit multiple versions
with different target capabilities enabled, probably for elaborate code that
_doesn't_ use any fancy builtins, right? It seems this is a shortcut for
static inline __attribute__((always_iniline)) implementation () { ... }
symbol __attribute__((target("msse2"))) { implementation(); }
symbol __attribute__((target("msse3"))) { implementation(); }
...
and so should be fully handled by the frontend (if at all, it seems to
be purely syntactic sugar).
I'd like to see it omitted initially - we should get the core stuff right
and build "nice" stuff ontop of it later, if necessary.
>>> The attribute can be scaled to support many versions but allowing a
>>> comma separated list of values for the mversion attribute. For
>>> instance, “__attribute__(mversion(“sse3”, “sse4”, ...)) will provide a
>>> version for each. For N attributes, N clones plus one clone for the
>>> default case will have to be generated by the compiler. The arguments
>>> to the "mversion" attribute will be similar to the arguments supported
>>> by the "target" attribute.
>>>
>>> This attribute is useful if the same source is going to be used to
>>> generate the different versions. If this has to be done manually, the
>>> user has to duplicate the body of the function and specify a target
>>> attribute of “popcnt” on one clone. Then, the user has to use
>>> something like IFUNC support or manually write code to call the
>>> appropriate version. All of this will be done automatically by the
>>> compiler with this new attribute.
>>>
>>> * Case II - User Guided Versioning where the function bodies for each
>>> version differ and is provided by the user.
>>>
>>> This case pertains to multi-versioning when the source bodies of the
>>> two or more versions are different and are provided by the user. Here
>>> too, I want to use a new attribute, “version”. Now, the user can
>>> specify versioning intent like this:
>>>
>>> int __attribute__((version(“popcnt”))
>>> find_popcnt(unsigned int i)
>>> {
>>> // inline assembly of the popcnt instruction, specialized version.
>>> asm(“popcnt ….”);
>>> }
>>>
>>> int
>>> find_popcnt(unsigned int i)
>>> {
>>> //generic code for doing this
>>> ...
>>> }
>>>
>>> This uses function overloading to specify versions. The compiler will
>>> understand that versioning is requested, since the functions have
>>> different attributes with "version", and will generate the code to
>>> execute the right function at run-time. The compiler should check for
>>> the existence of one body without the attribute which will be the
>>> default version.
Yep, we agreed that this is a good idea. But we also agreed to
use either the target attribute (for compiler-generated tests) or
a single predicate attribute that takes a function which is const
with no arguments and returns whether the variant is selected or not.
>>> * Case III - Versioning is done automatically by the compiler.
>>>
>>> I want to add a new compiler flag “-mversion” along the lines of “-m”.
>>> If the user specifies “-mversion=popcnt” then the compiler will
>>> automatically create two versions of any function that is impacted by
>>> the new instruction. The difference between “-m” and “-mversion” will
How do you plan to detect "impacted by the new instruction?". Again
popcnt seems to be a poor example - most use probably lies in
autovectorization (but then it's closely tied to active capabilites of the
backend and not really ready for auto-versioning).
This will be a lot of work if it shouldn't be very inefficient.
Richard.
>>> be that while “-m” generates only the specialized version, “-mversion”
>>> will generate both the specialized and the generic versions. There is
>>> no need to explicity mark any function for versioning, no source
>>> changes.
>>>
>>> The compiler will decide if it is beneficial to multi-version a
>>> function based on heuristics using hotness information, code size
>>> growth, etc.
>>>
>>>
>>> Runtime support
>>> ===============
>>>
>>> In order for the compiler to generate multi-versioned code, it needs
>>> to call functions that would test if a particular feature exists or
>>> not at run-time. For example, IsPopcntSupported() would be one such
>>> function. I have prepared a patch to do this which adds the runtime
>>> support in libgcc and supports new builtins to test the various
>>> features. I will send the patch separately to keep the dicussions
>>> focused.
>>>
>>>
>>> Thoughts?
>>
>> Please focus on one mechanism and re-use existing facilities as much as
>> possible. Thus, see the old discussion where we settled on overloading
>> with either using the existing target attribute or a selector function.
>> I don't see any benefit repeating the discussions here.
>>
>> Richard.
>>
>>> Thanks,
>>> -Sri.
>>>
>>
>
next prev parent reply other threads:[~2011-08-17 15:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-16 20:38 Sriraman Tallam
2011-08-16 21:06 ` Xinliang David Li
2011-08-16 21:24 ` Xinliang David Li
2011-08-17 7:29 ` Richard Guenther
2011-08-17 14:53 ` Xinliang David Li
2011-08-17 15:12 ` Richard Guenther [this message]
2011-08-17 16:38 ` Xinliang David Li
2011-08-18 7:51 ` Richard Guenther
2011-08-18 8:05 ` Xinliang David Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAFiYyc2=GhrA+pE46ZTqkQkD+PqETM+1Ht5Aj3CVLzsqXm7uWA@mail.gmail.com' \
--to=richard.guenther@gmail.com \
--cc=davidxl@google.com \
--cc=gcc@gcc.gnu.org \
--cc=tmsriram@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).