|Tux| | Holy shizzles! | 08:09 | |
This is Rakudo version 2016.05-64-g1254bbe built on MoarVM version 2016.05-18-g1339332 | |||
test 18.442 | |||
test-t 11.323 | |||
csv-parser 22.029 | |||
DrForr | Someone a few months back mentioned an adverb or something to add to here-docs in order to completely suppress interpolation of {} blocks in strings - Got a handy link? | 08:16 | |
Maybe the :c adverb?... | 08:19 | ||
Wrong channel, sorry. | |||
masak | [Tux]: wow! o.O | 08:31 | |
that... is no longer noise. | |||
timotimo | that could be liz' for loop improvements? | 08:41 | |
jnthn | morning, #p6dev | 09:11 | |
Measuring stuff using time is going to be pretty noisy, but yeah, the trend has been downwards of late. :) | 09:12 | ||
masak .oO( the trend lines indicate we'll be hitting negative numbers by 2019 ) | 09:17 | ||
jnthn | :D | 09:18 | |
jnthn is doing callgrind measurements on most of his opts these days, which lack the noise (and are slooow :)) | 09:19 | ||
m: say ::(q/$*IN/).WHAT | 09:33 | ||
camelia | rakudo-moar 1254bb: OUTPUTĀ«(Failure)ā¤Ā» | ||
jnthn | hmm | ||
dalek | kudo/nom: d86dc49 | lizmat++ | src/core/Any-iterable-methods.pm: Further 8% improvement on @a.map in sink context - remove superfluous nqp::stmts - use native int flag to indicate status |
09:43 | |
kudo/return-without-lexotic: f99bb9a | jnthn++ | src/core/Exception.pm: Update Exception.fail after return changes. |
|||
jnthn | Well, that gets me down to less than 10 failing test files in that branch.. :) | 09:44 | |
Ven | .tell brrt interesting LuaJIT talk by one of the current DartVM engineers: mrale.ph/talks/vmss16 | 09:50 | |
ah, no bot here? | 09:52 | ||
timotimo | no :( | ||
alas, i haven't been able to figure out who owns this instance of yoleaux | 09:53 | ||
Ven | okay! well, yolo'd in the other channel. thanks timo :) | ||
timotimo | mhm | ||
Ven | (you also might be interested in that talk) | ||
masak .oO( you only live eauxnce ) | 10:08 | ||
dalek | kudo/nom: 9942c42 | lizmat++ | src/core/Any-iterable-methods.pm: Decont label at iterator creation |
11:30 | |
masak .oO( all this talk of decanting makes me want some wine ) | 11:31 | ||
nine | How expensive is deconting actually? | ||
I'd naĆÆvely expect it to be just a pointer dereference post JIT | 11:32 | ||
jnthn | It's not quite that simple yet, but close | 11:56 | |
It's as cheap as an attribute access | |||
It's a tad more expensive 'cus we have to do a "was this mixed into" check, but there's plans to eliminate it | 11:57 | ||
At which point it will be really just a pointer check | |||
uh, pointer deref | |||
masak .oO( pointer decaf ) | 11:58 | ||
lizmat | yeah, but if it isn't needed in a loop, why put it in a loop, however small, right | ||
? | |||
jnthn | Well, if it's not needed then we might rip it out entirely, but it may still cost a guard... :) | 12:01 | |
lizmat | pretty sure it's needed, but let me double check :-) | 12:03 | |
nine | lizmat: oh your change looks absolutely reasonable to me :) I was just curious. | 12:10 | |
nine hasn't given deconts much thought before | |||
dalek | kudo/nom: 3d50c98 | lizmat++ | src/core/Any-iterable-methods.pm: The label case also handled by no phaser case It only adds about 1% overhead, but it will make optimising the phasers case a lot more simple. |
12:17 | |
lizmat | the decont is necessary | 12:29 | |
dalek | kudo/nom: 2bd4211 | lizmat++ | src/core/Any-iterable-methods.pm: Remove now unnecessary CAN_FIRE_PHASERS flag |
12:57 | |
lizmat | afk& | ||
dalek | kudo/return-without-lexotic: 198ac34 | jnthn++ | src/Perl6/World.nqp: Avoid CONTROL swallowing return control exception. Since `return` now uses real control exceptions, we need to be a bit more careful when using a `return` in a block with a `CONTROL`. In NQP especially, since we don't have the need to match on an exception type. |
13:21 | |
kudo/return-without-lexotic: a0f0a17 | jnthn++ | src/Perl6/World.nqp: Extend handling of colonpair canon. in setting. We'll soon be able to switch `return` to be a sub. However, doing so fixes evaluating code that does a `return` while compiling the setting. That in turn meant that we produced some better code at compile-time for certain colonpairs, which in turn triggered an unhandled case in canonicalization, which broke setting compilation. |
14:07 | ||
kudo/return-without-lexotic: 85af0aa | jnthn++ | src/core/control.pm: Turn `return` and `return-rw` into subs. Meaning they're compile-time declarations rather than late-bound symbols, which opens them up to much better compiler optimization. |
14:08 | ||
p/return-without-lexotic: 6822d3a | jnthn++ | src/vm/moar/QAST/QASTOperationsMAST.nqp: Make lex throw ops as not static-inlinable. |
14:41 | ||
kudo/return-without-lexotic: 28d2c84 | jnthn++ | src/core/control.pm: Break out `return` into multi candidates. Which are simpler and should be something the VM can inline. |
14:51 | ||
MasterDuke | any idea why rakudo has ~40 instances of 'my $no-sink; ...; $no-sink := $target.push(...) ...;'? | 17:10 | |
in at least a couple of the places the spec-tests all pass if you remove the $no-sink entirely and performance seems to improve slightly | 17:11 | ||
[Coke] | MasterDuke: were they added by Larry? | 17:12 | |
ISTR he did a lot of sink work immediately pre-xmas | |||
lizmat | it's because if we don't put a $no-sink there, the .sink method will be called on the rsult | 17:13 | |
which is something we may not want for some situations | |||
that's at least my understanding of it | 17:14 | ||
nine | yes, that's the reason | 17:16 | |
b2gills | There are performance reasons, and API reasons for $no-sink | ||
MasterDuke | hmm. looking at a profile before and after removing it from Iterator.push-all, the number of sink calls is the same | 17:17 | |
geekosaur | it will depend on the context in which it occurs | 17:28 | |
MasterDuke | in all the profiles i've looked at the performance is better without $no-sink. also, the spec-tests pass | 17:58 | |
just trying to learn more here, are the API reasons documented anywhere i could take a look at? | 17:59 | ||
timotimo | it could very well be that Iterator.push-all isn't covered at all by the spec tests? | 18:00 | |
MasterDuke | not sure i want to profile all the spec-tests to find out... | 18:02 | |
guess i can look for something like code i was running | |||
timotimo | maybe not profile ... | ||
i have a branch of MoarVM that allows you to get a line-by-line coverage report | |||
it's not perfect, because for many lines we don't record annotations at all, but a simple grep over moar --dump foo.moarvm helps with that | 18:03 | ||
MasterDuke | well, S32-str/split-simple.t has "split_test 'a1b24f'.split(/\d+/), <a b f>, 'Str.split(/regex/)';" | 18:04 | |
which looks pretty close to what i was doing, but i don't know all the other contexts Iterator.push-all could be called in | 18:05 | ||
timotimo | some custom iterators may implement their own push-all for performance reasons | 18:08 | |
MasterDuke | then wouldn't they not care if the default one changes? | 18:09 | |
timotimo | correct. that's why you might not see spec test fallout from changing the no-sink in there | ||
MasterDuke | there are only 6 calls to any push-all in all of rakudo | 18:12 | |
timotimo shrugs | 18:13 | ||
i haven't dipped my toe into iteration code in a long while | |||
lizmat | MasterDuke: but those few ones are hot code paths, afaik | 18:14 | |
MasterDuke | 2 are in Array.pm, 2 are in List.pm, 1 in metaops.pm, and 1 in Iterator.pm | 18:16 | |
it looks like Array and List are redifining their own push-all | 18:17 | ||
Iterator is obviously using its own, i think metaops is using Iterator's | |||
well yeah, if those are hot paths wouldn't it make sense to optimize them as much as possible? | 18:18 | ||
interesting. Array.kv creates a new Seq which does Iterator and defines its own push-all, which is a bit different since it pushes both key and value, but neither of those pushs are sunk | 18:25 | ||
just '$target.push(nqp::p6box_i($key));' and '$target.push($pulled);' | |||
the other two push-alls redefined in Array do $no-sink their push | 18:26 | ||
oops, sorry, that was List | 18:27 | ||
dalek | kudo/nom: 30b33e3 | lizmat++ | src/core/Any-iterable-methods.pm: Make @a.map with phasers about 10% faster - use native int flags where possible Couldn't do this for $!NEXT, because apparently using a native int attribute in a nqp::if() is a very bad thing to do performance wise (like making the whole iterator logic 2x as slow) - initialize the $!NEXT flag at iterator creation time Probably didn't matter, but part of trying to get rid of the $!did-init logic. - use nqp::if instead of postfix if/unless To at least make this piece of code consistent. - use a native int flag for running state Rather than checking for IterationEnd. 965ca6a | lizmat++ | src/core/Any-iterable-methods.pm: Squeeze a few more % out of @a.map with phasers - turn the if/else into a ternary inside the loop Oddly enough, it turned out to be impossible to make the outer while loop a postfix while (either with "while" or with nqp::while): It would give "Cannot reference undeclared local '__lowered_lex_3194" during the MAST stage. |
18:41 | |
lizmat | MasterDuke: thanks for the extra set of eyes | ||
the maze can be quite intimidating at times :-) | |||
jnthn: would it make sense to create a setting global $NO-SINK for stuff to be not sinked to ? | 18:44 | ||
so at least we wouldn't need to burden local scopes with its creation ? | |||
MasterDuke | lizmat: you're welcome, it's fun | ||
jnthn | lizmat: No | 18:48 | |
lizmat: It'll prevent inlining | |||
lizmat | ok | ||
jnthn: even if it is a lexcial ? | 18:49 | ||
*lexical ? | |||
jnthn | Yes, things that refer to lexical variables outside of their scope can't be inlined. | ||
lizmat | so: my $no-sink; for { $no-sink := ... } would be bad ? | 18:50 | |
jnthn | That's OK, I thought you meant moving it out further than the routine? | ||
(e.g. setting global) | |||
The other reason setting global would be bad is that it'll hurt concurrency | 18:51 | ||
By creating loads of contention on the cache line | |||
Holding the var | |||
MasterDuke | fyi, i tried removing all $no-sinks from all push-alls, so far all spec-tests have passed, but spec/integration/advent2013-day14.t appears to have hung | ||
that may have just been from setting TEST_JOBS=6, it passes when run by itself | 18:53 | ||
lizmat | jnthn: ok, message received :-) | 18:54 | |
kudo/nom: 0a16ed5 | TimToady++ | src/Perl6/Actions.nqp: always mark enum expression as wanted Previously we only marked comma lists, but there are other ways to generate lists, including range ops. |
19:48 | ||
MasterDuke | after a break for errands, ran a complete spectest with all $no-sinks removed from all push-alls, everything passed | 19:51 | |
lizmat | MasterDuke: try making a class with a .sink method that says "sunk", then put it in a list and iterate over it | 19:53 | |
it should never say "sunk" | 19:54 | ||
we should probably need to add tests for this | |||
dalek | kudo/nom: 072a6c2 | lizmat++ | src/core/Any-iterable-methods.pm: Make @b = @a.map with phasers about 20% faster - use nqp::eqaddr instead of =:= - use nqp::not_i instead of ! - remove nqp::stmts where possible by reducing number of lines to 1 - use postfix if where possible |
19:59 | |
MasterDuke | m: my class A { method sink { say "sunk"; } }; say "hi" for (A.new, A.new) | ||
camelia | rakudo-moar 965ca6: OUTPUTĀ«hiā¤hiā¤Ā» | ||
MasterDuke | lizmat: like that? i get the same output on my build | ||
lizmat | m: my class A { method sink { say "sunk"; } }; A.new | 20:00 | |
camelia | rakudo-moar 965ca6: OUTPUTĀ«sunkā¤Ā» | ||
lizmat | hmmm | ||
lizmat would love to be able to get rid of $no-sink | 20:01 | ||
jnthn: opinions ?? ^^ | |||
[Coke] | gah, TimToady++ is comitting again! ;) | 20:02 | |
jnthn | I'm pretty sure they're there for a reason...would be good to add tests. | 20:17 | |
I'd rather not second-guess 'em | |||
And break stuff | |||
lizmat | jnthn: another weird thing: | 20:20 | |
m: use nqp; class A { has int $.a; method a() { nqp::if($!a,42) } }; my $a = A.new; for ^1000000 { $a.a }; say now - INIT now | |||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.54265644ā¤Ā» | ||
lizmat | m: use nqp; class A { has $.a; method a() { nqp::if($!a,42) } }; my $a = A.new; for ^1000000 { $a.a }; say now - INIT now | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.33593612ā¤Ā» | ||
lizmat | m: say .543 / .336 | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«1.616071ā¤Ā» | ||
lizmat | jnthn: so, using a native int attribute in an nqp::if() is 1.6x slower than not using a native int | 20:21 | |
jnthn: should I rakudo bug this performance difference ? | 20:22 | ||
jnthn | NO | ||
*No | |||
lizmat | ok | ||
jnthn | Note that you're if is not in void context there | ||
So there's very probably a boxing going on at some point | 20:23 | ||
Oh | |||
lizmat | even if I put it in void context, I see similar numbers | 20:24 | |
jnthn | And since it's a method call also...we don't know | ||
Oh, no, you accessed it as $!a | |||
Hm, more curious in void context. | |||
Though did you do it with nqp::if or a statement if? | |||
lizmat | m: use nqp; class A { has int $.a; method a() { nqp::if($!a,42) } }; my $a = A.new; for ^1000000 { $a.a; Nil }; say now - INIT now | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.3547077ā¤Ā» | ||
lizmat | m: use nqp; class A { has $.a; method a() { nqp::if($!a,42) } }; my $a = A.new; for ^1000000 { $a.a; Nil }; say now - INIT now | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.24572299ā¤Ā» | ||
lizmat | m: say .358 / 246 | 20:25 | |
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.0014553ā¤Ā» | ||
jnthn | But it's not in void context in method a | ||
lizmat | m: say .358 / .246 | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«1.455285ā¤Ā» | ||
jnthn | So it's still being returned | ||
m: use nqp; class A { has $.a; method a() { nqp::if($!a,42); Nil } }; my $a = A.new; for ^1000000 { $a.a }; say now - INIT now | 20:26 | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.50680681ā¤Ā» | ||
jnthn | m: use nqp; class A { has $.a; method a() { nqp::if($!a,42); Nil } }; my $a = A.new; for ^1000000 { $a.a }; say now - INIT now | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.47445983ā¤Ā» | ||
jnthn | Hm, curious | ||
lizmat | m: use nqp; class A { has int $.a; method a() { nqp::if($!a,42); Nil } }; my $a = A.new; for ^1000000 { $a.a }; say now - INIT now | 20:27 | |
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.57380869ā¤Ā» | ||
jnthn | m: use nqp; class A { has $.a; method a() { nqp::if($!a,42); Nil } }; my $a = A.new; for ^1000000 { $a.a; Nil }; say now - INIT now | ||
camelia | rakudo-moar 072a6c: OUTPUTĀ«0.5022255ā¤Ā» | ||
lizmat | fwiw, in a profile I see a IntAttrRef allocation for each iteration | ||
jnthn | Ah | 20:28 | |
lizmat | is that to be expected ? | ||
jnthn | Yes, in so far as we're not always very good at optimizing them away :) | ||
Spesh doesn't understand them at all yet. | |||
lizmat | ok, then I suggest this be a LHF for optimizing rakudo | ||
because there's a lot of them in the core | 20:29 | ||
or there *could* be a lot of them | |||
jnthn | Well, except spesh and Moar are improving continually also :) | ||
MasterDuke | btw, re the $no-sinks, not all the push-alls had them. with the admittedly quick run through the code i did, i didn't notice any obvious reason why some did and some didn't | 20:30 | |
lizmat | well, I'm about to basically remove all native int attributes from the core for this reason | ||
jnthn | I wouldn't | ||
lizmat | MasterDuke: sometimes you can be sure there won't be an object that has a custom .sink | ||
jnthn: I would mark them as fixable as soon as spesh / optimizer knows how to grok native attributes properly | 20:31 | ||
jnthn | What are you going to change them to? Bool? | 20:32 | |
lizmat | Int I guess | ||
jnthn | OK, but what else happens with them? | 20:34 | |
lizmat | usually they're set to 1 to indicate some condition has been met | ||
jnthn | I mean, presumably they're getting set/incremented instead of just read/boolified all the time | ||
Ah | |||
Then bool is more natural? :) | |||
lizmat | yeah, but then I would need to say = True and then later when native ints *would* work fast, I would have to change more than just the declaration | 20:35 | |
jnthn | True | 20:37 | |
It's fairly clear, I think, that the native int one will be the more optimizable | |||
Up to you if you want to change it now, then change it back later | |||
lizmat | ok, it's a deal :-) | 20:38 | |
jnthn | Dunno if you saw the result on #moarvm earlier today, but in the branches I'm working on improving return, `sub foo($a) { if $a { return 1 } }; for ^2000000 { foo(1) }` runs in around half the time | 20:40 | |
lizmat | cool! | ||
brrt | yes, really cool | 20:42 | |
also, please don't kill the natives :-) | 20:44 | ||
how else are we going to show off the new spesh/jit swagger | |||
lizmat | brrt: you fix native int attribute performance, I'll put them back in the core, ok ? :-) | ||
brrt | sounds like a plan, except that i don't really know the details | 20:45 | |
:-) | |||
lizmat | I mean, 5+% performance improvement on @a.map by just doing s/int/Int/ is too easy a change to not do | 20:46 | |
brrt | actually, i'm going to sleep, i'll have to wake up early enough tomorrow | ||
lizmat | good night, brrt | ||
brrt | aye... just renember to change it back when we've proven the reverse is better | ||
see you! | |||
dalek | kudo/nom: 60731a0 | lizmat++ | src/core/Any-iterable-methods.pm: Make @a.map with phaser about 5% faster still It appears native int attributes incur an overhead that is still not optmized away. So, until then we'll use Int instead of int and mark these lines for change when things get better. See irclog.perlgeek.de/perl6-dev/2016-0...i_12630061 |
20:54 | |
jnthn | Rest time...hopefully I'll get a little more time on the return stuff tomorrow to fix the last regression. After that, will need to port a few changes to the JVM. | 21:31 | |
*JVM backend | 21:32 | ||
lizmat | good night, jnthn | 21:33 | |
MasterDuke | lizmat: since i've already done the work of removing those $no-sinks, would it be a problem to put them in a PR, in case it's decided to get rid of them at some point? | 21:54 |