[prev in list] [next in list] [prev in thread] [next in thread] 

List:       perl5-porters
Subject:    Re: use of LIKELY() and UNLIKELY() branch predictors
From:       bulk88 <bulk88 () hotmail ! com>
Date:       2013-01-31 19:13:04
Message-ID: BLU0-SMTP72F6F1A6B2ACF502A5E2FDDF1D0 () phx ! gbl
[Download RAW message or body]

Steffen Mueller wrote:
> On 01/30/2013 07:33 PM, Dave Mitchell wrote:
>> Yeah. Just to be clear, I was pointing out the difficulties of automatic
>> profiling: I expect it would usually be obvious when to apply UNLIKELY 
>> etc
>> by hand.
> 
> That's an interesting point of view. Many a potential big win would be 
> based on knowledge of relative frequency of occurrence of SV types. That 
> isn't at all obvious. Some things are: SvMAGICAL could almost always be 
> wrapped in UNLIKELY -- unless we're already in a branch that treats a 
> special case. This shows that those decisions are highly context 
> sensitive and thus aren't necessarily all that beginner-friendly.

How often is @ISA's magic run? Does utf8/swash loading use magic at all?

 > Furthermore for UTF8 handling,
> there's lots of loops over characters, checking
> 
> if (UNI_IS_INVARIANT(uv))
> 
> which is:
> 
> /* Is the representation of the Unicode code point 'c' the same 
> regardless of
>  * being encoded in UTF-8 or not? */
> #define UNI_IS_INVARIANT(c)        (((UV)c) <  0x80)
> 
> Is it a fair assumption to think that most characters we deal with are < 
> 0x80? For the code I write, I'm pretty sure that yes, most characters 
> are UNI_IS_INVARIANT (yay, ASCII). But is it reasonable to discriminate 
> this way? If so, that could be a big win.

Someone's data could be 100% non latin 1. The whole world isn't written 
in latin script.


> 
> There's easy cases, too: Anything that does if(...)croak() could be 
> considered unlikely because of the relative cost of exceptions.

Except for pp_die, I think the other croaks and panics can be 
deoptimized. I've slowly been doing that over time with the interp 
(nocontext croaks, wrappers around croak that add a common format 
string, so in the caller just 1 arg is put on C stack, not 2 or 3, etc).

> 
> Finally, looking at what I think is a very hot function:
> 
> SV *Perl_newSV(pTHX_ const STRLEN len)
> 
> One could argue that if(len) should be unlikely.

Some (not all) len != 0 callers.
Perl_hv_common
3 calls S_unpack_rec
pp_backtick
S_make_trie
S_find_byclass
S_scan_const
Perl_scan_num
S_swatch_get
Perl_upg_version
Perl_my_cxt_init
XS_DynaLoader_CLONE
pp_ssockopt
pp_getpeername

> 
> Would it be beneficial to add a separate function that only allocates a 
> new SV without checking whether we should reserve string space? It seems 
> to me like the majority of SVs aren't born as strings, so that could be 
> a similar change as SvREFCNT_dec_NN in that it saves one branch in very 
> hot code.

I dont think so, but what can be done is replacing the SvGROW with an 
absolute sv_grow (we know SvLEN will be 0 on a fresh SV and it is not a 
COW) and get rid of the sv_upgrade (grow will do an upgrade anyway). 
Preprocessed code ahead.
_____________________________________________________________
     if (len) {
         Perl_sv_upgrade(my_perl, sv, SVt_PV);
         (((sv)->sv_flags & 0x00010000)
          || ((XPV *) (sv)->sv_any)->xpv_len_u.xpvlenu_len < (len + 1) ? 
Perl_sv_grow(my_perl, sv,
 
               len +
 
               1) : ((sv)->sv_u.
 
                     svu_pv));
     }
_____________________________________________________________
-O1 asm code looks like this for me
_____________________________________________________________
   if ( len )
   {
     Perl_sv_upgrade(my_perl, sv, SVt_PV);
     if ( *((char *)(&sv->sv_flags) + 1) & 1 || 
sv->sv_any->xpv_len_u.xpvlenu_len < len + 1 )
       Perl_sv_grow(my_perl, sv, len + 1);
   }
_____________________________________________________________

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic