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