This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] powerpc: New feature - HWCAP/HWCAP2 bits in the TCB


On Mon, 2015-06-29 at 11:53 +0100, Richard Henderson wrote:
> On 06/09/2015 04:06 PM, Steven Munroe wrote:
> > On Tue, 2015-06-09 at 15:47 +0100, Szabolcs Nagy wrote:
> >>
> >> On 08/06/15 22:03, Carlos Eduardo Seo wrote:
> >>> The proposed patch adds a new feature for powerpc. In order to get
> >>> faster access to the HWCAP/HWCAP2 bits, we now store them in the TCB.
> >>> This enables users to write versioned code based on the HWCAP bits
> >>> without going through the overhead of reading them from the auxiliary
> >>> vector.
> >
> >> i assume this is for multi-versioning.
> >
> > The intent is for the compiler to implement the equivalent of
> > __builtin_cpu_supports("feature"). X86 has the cpuid instruction, POWER
> > is RISC so we use the HWCAP. The trick to access the HWCAP[2]
> > efficiently as getauxv and scanning the auxv is too slow for inline
> > optimizations.
> >
> 
> There is getauxval(), which doesn't scan auxv for HWCAP[2], but rather reads 
> the variables private to glibc that already contain this information.  That 
> ought to be fast enough for the builtin, rather than consuming space in the TCB.
> 

Richard I do not understand how a 38 instruction function accessed via a
PLT call stub (minimum 4 additional instructions) is equivalent or "as
good as" a single in-line load instruction.

Even with best case path for getauxval HWCAP2 we are at 14 instructions
with exposure to 3 different branch miss predicts. And that is before
the application can execute its own __builtin_cpu_supports() test.

Lets look at a real customer example. The customer wants to use the P8
128-bit add/sub but also wants to be able to unit test code on existing
P7 machines. Which results in something like this:

static inline vui32_t
vec_addcuq (vui32_t a, vui32_t b)
{
        vui32_t t;

                if (__builtin_cpu_supports("PPC_FEATURE2_HAS_VSXâ))
                {
                
                        __asm__(
                            "vaddcuq %0,%1,%2;"
                            : "=v" (t)
                            : "v" (a),
                              "v" (b)
                            : );
                }
                else
                        vui32_t c, c2, co;
                        vui32_t z= {0,0,0,0};
                        __asm__(
                            "vaddcuw %3,%4,%5;\n"
                            "\tvadduwm %0,%4,%5;\n"
                            "\tvsldoi %1,%3,%6,4;\n"
                            "\tvaddcuw %2,%0,%1;\n"
                            "\tvadduwm %0,%0,%1;\n"
                            "\tvor %3,%3,%2;\n"
                            "\tvsldoi %1,%2,%6,4;\n"
                            "\tvaddcuw %2,%0,%1;\n"
                            "\tvadduwm %0,%0,%1;\n"
                            "\tvor %3,%3,%2;\n"
                            "\tvsldoi %1,%2,%6,4;\n"
                            "\tvadduwm %0,%0,%1;\n"
                            : "=&v" (t), /* 0 */
                              "=&v" (c), /* 1 */
                              "=&v" (c2), /* 2 */
                              "=&v" (co) /* 3 */
                            : "v" (a), /* 4 */
                              "v" (b), /* 5 */
                              "v" (z)  /* 6 */
                            : );
                        t = co;
                }
        return (t);
}

So it is clear to me that executing 14+ instruction to decide if I can
optimize to use new single instruction optimization is not a good deal.

One instruction (plus the __builtin_cpu_supports which should be and
immediate,  branch conditional) is a better deal. Inlining so the
compiler can do common sub-expression about larger blocks is an even
better deal.

I just do not understand why there is so much resistance to this simple
platform ABI specific request.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]