Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^5: XS: EXTEND/mPUSHi

by syphilis (Canon)
on Sep 27, 2011 at 00:39 UTC ( #927986=note: print w/ replies, xml ) Need Help??


in reply to Re^4: XS: EXTEND/mPUSHi
in thread XS: EXTEND/mPUSHi

but that still leaves me with the question of whether I should be resetting the stack to account for the single input parameter, or whether the EXTEND() takes care for that for me

No - as it stands, the first value that gets returned should be the supplied argument - at least that's what I'm finding. If you want to avoid that, then you need to reset the stack pointer or take some alternative measure.
Ike questions the validity of doing sp = mark though it's something that has been in the Inline test suite for the last few years, and has not produced any problems with the cpan-testers. Is there a better way of resetting the stack pointer ?
I think that, in this instance you could also just sp--; (update: or, more generally, sp -= items) before you EXTEND.

I can't actually find any code of mine that resets the stack pointer - I usually take a different approach such as just assigning to ST(0), ST(1), etc.

I also wonder if I shouldn't be passing in a reference to the an array and populating it directly, rather than assigning the returned stack to it?

I've benchmarked that for some huge arrays in the past ... and not detected any advantage in passing by reference (with Inline::C).

Cheers,
Rob


Comment on Re^5: XS: EXTEND/mPUSHi
Select or Download Code
Re^6: XS: EXTEND/mPUSHi
by ikegami (Pope) on Sep 27, 2011 at 01:33 UTC

    xsubpp currently generates SP -= items;.

    That change to the stack pointer is lost, since it's done in the real XS function (the wrapper), which doesn't doesn't "publish" the change using PUTBACK before calling the wrapped function.

    I'd make Inline::C call PUTBACK before calling the wrapper function and make Inline_Stack_Reset a no-op.

    In two places:

    PPCODE: + PUTBACK; temp = PL_markstack_ptr++;

    Update: I thought there would be backwards compatibility issues, but there aren't. ST(0) and such will still get the args. Adjusted.

      I'd make Inline::C call PUTBACK before calling the wrapper function and make Inline_Stack_Reset a no-op

      Thanks - something to think about.
      Of course, while there's not actually anything that's broken, I'm inclined to leave things as they are.

      Cheers,
      Rob

        Hm. If you consider this "not broken", then I guess it isn't. Hm. If you consider this "not broken", then I guess it isn't.

        But if some of that seems unnecessary, then ... :)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^6: XS: EXTEND/mPUSHi
by BrowserUk (Pope) on Sep 27, 2011 at 07:21 UTC
    I've benchmarked that for some huge arrays in the past ... and not detected any advantage in passing by reference (with Inline::C).

    I'm guessing that you were populating the passed-by-reference Av with new SVs?

    This (rnd64i( int n, SV *avref ) (i for inplace--terrible name)), assumes a pre-populated (not just pre-sized) array of n scalars into which it then sets the values to be returned. The Perl code contrasts ARGV[0] calls for 1 million values each time, with the same for rand64() which returns them on the stack and assigns them to an array.

    #! perl -slw use strict; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'END_C', NAME => 'monkeys', CLEAN_AFTER_BUILD => 0; void rnd64( int n ) { dXSARGS; static unsigned __int64 y = 88172645463325252i64; SP = MARK; EXTEND( SP, n ); while( n-- ) { y ^= y << 13; y ^= y >> 7; y ^= y << 17; mPUSHu( y ); } PUTBACK; return; } void rnd64i( int n, AV* av ) { dXSARGS; SV **ary = AvARRAY( av ); static unsigned __int64 y = 88172645463325252i64; SP = MARK; while( n-- ) { y ^= y << 13; y ^= y >> 7; y ^= y << 17; sv_setuv( ary[ n ], y ); } PUTBACK; return; } END_C use Data::Dump qw[ pp ]; use Devel::Peek; use Time::HiRes qw[ time ]; my $start = time; my @rands = (1) x 1e6; for( 1 .. $ARGV[0] ) { @rands = rnd64( 1e6 ); } my $stop = time; printf "stack->array assign: Rate: %.9f\n", ( $stop - $start ) / ( 1 +e6 * $ARGV[ 0 ] ); $start = time; my @rands2 = (1) x 1e6; for( 1 .. $ARGV[0] ) { @rands = rnd64i( 1e6, \@rands2 ); } $stop = time; printf "Modify array in-place: Rate: %.9f\n", ( $stop - $start ) / ( 1 +e6 * $ARGV[ 0 ] ); exit;

    The result is rnd64i() is up to 100 times faster:

    C:\test>Monkeys 1 stack->array assign: Rate: 0.000011359 Modify array in-place: Rate: 0.000000121 C:\test>Monkeys 10 stack->array assign: Rate: 0.000001353 Modify array in-place: Rate: 0.000000037 C:\test>Monkeys 100 stack->array assign: Rate: 0.000000365 Modify array in-place: Rate: 0.000000030

    That's a saving worth having.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      I'm guessing that you were populating the passed-by-reference Av with new SVs?

      Quite possibly - looking at those figures I must have been doing *something* dumb :-)

      Cheers,
      Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://927986]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2014-11-29 00:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (200 votes), past polls