develooper Front page | perl.perl5.porters | Postings from February 2013

Re: OP_PADSV_NOLV

Thread Previous | Thread Next
From:
bulk88
Date:
February 28, 2013 19:16
Subject:
Re: OP_PADSV_NOLV
Message ID:
BLU0-SMTP157D25CEA99A0E24C5FC3F8DFFE0@phx.gbl
Steffen Mueller wrote:
> 
> By the way: did you know that pp_add is a pretty heavy OP? It's thanks 
> to the PRESERVE_UVIV logic relating to switching underlying types in 
> overflow situations and retaining maximum accuracy.
> 
> I wonder whether there are situations in which we know at compile time 
> that this logic is not needed. Probably not.
> 
> --Steffen

Going to 5.6 (or 5.8) all NV math makes perl practical for math again. 
Perl is the worst or almost worst language you can use for math, 
http://benchmarksgame.alioth.debian.org/u32/performance.php?test=nbody . 
  I've written about it before 
http://perlmonks.org/?node_id=990073;spoil=1 . I think the biggest 
problem is you can't check CPU carry/overflow flag in C so the 
"portable" way of doing it is very poor compared to using some asm x86 
and jumping on carry/overflow flag after the add. The other thing to do 
is >> and | INU/V flags on left and right SVs, then do a switch.

Another idea is factor out the use_left stuff into a different opcode or 
a different optree but I am not sure what use_left is on script 
level/optree level.

Maybe the targ assignment can be moved after the overload call. The asm 
is probably a DEBUGGING Perl I used due to Perl_pad_sv. It might move by 
itself on some compilers if Perl_pad_sv isnt a function (c compiler's 
peephole didn't look far enough to see targ isn't used after the 
overload call, and on the no overload branch there are no calls, so SP 
or pad array can't be changed by overload in a way that matters).

Another idea would be trim down some of the sv_set*v to use direct flag 
manipulation, call sv_setiv once with a UV or IV (pun it), then set the 
UV flag in pp_add by macro, dunno if that makes sense.

Next thing to think about is, if we Sv*VXed, aren't they guaranteed to 
be the correct type already and they can be set with pure macros since 
no upgrade is needed?

Compiler already did some punning/merging, for example

    538:             if (buvok)
    539:                 buv = ((XPVUV *) (svr)->sv_any)->xuv_u.xivu_uv
+;
2807D5E2 8B 09            mov         ecx,dword ptr [ecx]
2807D5E4 8B 49 10         mov         ecx,dword ptr [ecx+10h]
2807D5E7 23 C7            and         eax,edi
2807D5E9 3B C7            cmp         eax,edi
2807D5EB 0F 94 C0         sete        al
2807D5EE 84 C0            test        al,al
    540:             else {
2807D5F0 75 0A            jne         Perl_pp_add+14Bh (2807D5FCh)
    541:                 const IV        biv = ((XPVIV *) (svr)->sv_any
+)->xiv_u.xivu_iv;
    542:                 if (biv >= 0) {


"const IV        biv = ((XPVIV *) (svr)->sv_any
+)->xiv_u.xivu_iv;" has no instructions associated with it.

Ideally as I mentioned on perlmonks, if there is no eval/do and no bless 
or tie calls on the lexical, and a lexical is never passed to another 
sub, in a sub, use a different set of opcodes to create 2 or 3 paths 
(pure UV, pure IV, or pure NV math), then doing all operators on a 
statement using something close to machine math without using the SV 
abstraction or Perl stack, or place native machine numbers on the Perl 
stack (not SV *). I know NULLs now appear on the Perl stack in some 
cases. There is an unrealistically work level to introducing a 3rd VM 
into perl which is what this idea is. I guess there were plans a long 
time ago to have alternate optree optimizers/opcodes and override at 
runtime the ck_() funcs.

A slimmer idea would be an opcode that has a var len bitfield/array, it 
will do arbitrary math ops on a list/perl stack going down/up the stack 
with the intermediate number stored in a C auto. When it reaches the end 
of array it assigns to the last SV on the list.

$_[1] = (($a * 5) + $_[0])/$main::global;
pushmark, padsv, const, aelemfast, gvsv, aelemfast, megamathop(mul << 8 
| add << 4 | div), nextstate



Last choice is remove or deprecate/de-default it from the build process 
PERL_PRESERVE_IVUV as unmaintainable and a performance degradation. If 
you dont like FP rounding/precision, complain to your CPU/CC vendor, 
Perl is just a wrapper around your native C/POSIX support, I hear GCC 
now offers __float128. Perl is not an OS and emulator/hypervisor wrapped 
together in 1 binary.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About