Perl 6 - the future is here, just unevenly distributed

IRC log for #moarvm, 2017-01-27

| Channels | #moarvm index | Today | | Search | Google Search | Plain-Text | summary

All times shown according to UTC.

Time Nick Message
00:08 timotimo now that unicode sequence names are case insensitive we can encode them with the same table we've used for the unicode names themselves
00:09 timotimo encode/compress
00:09 timotimo though the shift-1 table from the names is probably almost 100% worthless for the sequences
00:24 samcv heh
00:24 samcv not totally
00:24 samcv not for the non-emoji ones
00:25 timotimo how many of those exist?
00:25 samcv http://www.unicode.org/Public/UCD/latest/ucd/NamedSequences.txt
00:25 samcv like 200? 300?
00:25 samcv lots of them have LETTER in it
00:26 samcv here is the gist https://gist.github.com/samcv/a5a8bc715d39f13aac7bdb8e8483597c with the shift's
00:28 timotimo oh, and all these syllables
00:28 timotimo OK, cool
00:28 timotimo and also WITH
00:30 samcv yea
00:31 samcv oh btw
00:31 samcv here are the provisional ones http://www.unicode.org/Public/UCD/latest/ucd/NamedSequencesProv.txt
00:31 samcv compare
00:31 geekosaur that kind of thing was why I poked at compressing by words; there's a *lot* of reuse
00:31 samcv KEYCAP NUMBER SIGN, to the emoji listing
00:31 samcv keycap: #
00:31 samcv is what it is in the emoji
00:31 samcv m: say "\c[keycap: *]"
00:31 camelia rakudo-moar d06d7c: OUTPUT«*️⃣␤»
00:32 samcv m: FE0F.uniname.say
00:32 camelia rakudo-moar d06d7c: OUTPUT«===SORRY!=== Error while compiling <tmp>␤Undeclared name:␤    FE0F used at line 1␤␤»
00:32 samcv m: 0xFE0F.uniname.say
00:32 camelia rakudo-moar d06d7c: OUTPUT«VARIATION SELECTOR-16␤»
00:34 timotimo that's a really short list
00:34 samcv the provisional is
00:34 timotimo yup
00:34 timotimo m: say uniname 0xFE0F
00:34 camelia rakudo-moar d06d7c: OUTPUT«VARIATION SELECTOR-16␤»
00:34 samcv but those are http://www.unicode.org/Public/emoji/4.0/emoji-sequences.txt here
00:34 timotimo ah
00:34 timotimo that's more like it
00:35 samcv keycap: 2, vs KEYCAP DIGIT TWO
00:35 samcv seems fine for us to support both
00:35 timotimo yeah
00:35 timotimo i'm going to bed early today
00:35 timotimo seeya!
00:35 samcv as long as the numbers are allowed otherwise can escape them
00:35 samcv bye!
00:35 timotimo o/
00:36 timotimo wait a minute ... we can't represent * or # in our base40 yet :o
00:36 timotimo another shift level, then?
00:36 samcv hah
00:36 samcv or just don't use shift level for it and store as normal string
00:37 samcv there's also non-ascii characters
00:37 timotimo if we can signal up front that we want a normal string there
00:37 timotimo oh, right, you mentioned that
00:37 samcv i mean they're gonna be stored in a separate structure
00:37 timotimo 1F1E8 1F1EE   ; Emoji_Flag_Sequence       ; Côte d’Ivoire                                                  # 6.0  [1] (????????)
00:37 samcv the sequences anyway
00:37 timotimo and also Åland Islands
00:38 samcv utf-8 encoded between  "" works fine in C yes?
00:38 samcv it just literally takes the data put there
00:38 samcv into the char *
00:38 timotimo i've never tried :)
00:38 samcv i'm pretty sure that's true
00:38 samcv would make less sense it it wasn't
00:38 timotimo stackoverflow would know. also, we want to be compatible to a whole bunch of platforms and their compilers
00:39 timotimo to be fair, that's gcc on almost all platforms, otherwise clang or msvc
00:39 samcv yeh it works perfect :) just tried with ????
00:39 samcv well i think C just puts whatever the fuck data you have in between
00:39 samcv so you can put really anything that uses 8 bits per thing
00:39 timotimo oh
00:39 samcv as long as it fits in 8 bits
00:40 timotimo we could use strings for our 16bit pieces, then :P
00:40 samcv since it's totally naive
00:40 samcv heh
00:40 timotimo except it'll probably be confused by \0 in the middle, and it'll put a \0 at the end, too
00:40 samcv madness
00:40 timotimo anyway, thinking about this is what costs me a lot of sleep
00:40 timotimo so i'll just drop it :)
00:40 samcv it's not stored literally as a \0 though
00:40 samcv only in the table
00:40 samcv and that's as a char
00:40 samcv hahah!
00:40 samcv sleep well
00:40 timotimo i'll try
00:41 timotimo have a good day :)
01:43 MasterDuke samcv: in radix(), for every char MVM_string_get_grapheme_at_nocheck() is called twice, which switches on the string's body.storage_type. so i pulled that check out and have a different while loop for every type
01:44 samcv nice
01:44 MasterDuke so it's definitely more efficient by work being done, but it makes the function about 3 times as big code-wise
01:44 MasterDuke which is why i'm guessing it isn't all that much faster
01:45 samcv hm
01:45 samcv link to code?
01:47 MasterDuke diff: https://gist.github.com/MasterDuke17/587545fd13e53cb66400f42751650bcd
01:50 pyrimidine joined #moarvm
02:02 samcv MasterDuke, would a list of unicode codepoints which have numeric values speed things up
02:03 samcv for the non-ascii side
02:03 samcv like if we had a switch
02:03 samcv actually the switch could have the ascii digits too
02:04 samcv then just go the length of the string and pass value to the switch of the grapheme
02:04 samcv and the compiler can optimize it
02:22 pyrimidine joined #moarvm
03:29 MasterDuke samcv: maybe
03:33 pyrimidine joined #moarvm
06:49 samcv MasterDuke, yeah i think that may be the fastest way to do it
07:04 pyrimidine joined #moarvm
07:11 domidumont joined #moarvm
07:18 domidumont joined #moarvm
07:51 pyrimidine joined #moarvm
08:22 domidumont joined #moarvm
08:23 domidumont joined #moarvm
08:44 zakharyas joined #moarvm
08:55 pyrimidine joined #moarvm
09:28 pyrimidine joined #moarvm
09:42 Ven joined #moarvm
10:28 pyrimidine joined #moarvm
10:53 pyrimidine joined #moarvm
11:20 ilmari[m] joined #moarvm
11:43 pyrimidine joined #moarvm
12:16 pyrimidine joined #moarvm
12:35 Ven joined #moarvm
13:41 pyrimidine joined #moarvm
13:44 pyrimidi_ joined #moarvm
13:54 samcv .ask timotimo so I have added some indexes to names.c for every other codepoint
13:54 yoleaux2 samcv: I'll pass your message to timotimo.
13:55 samcv see here: https://gist.github.com/samcv/ebbcf638b92501ac71e22f4dde1a510f
13:55 samcv also we don't store any codepoints without names anymore
13:57 samcv we call uninames with a codepoint number, if it returns 0 then uninames has generated the codepoint's name such as <control-0000>, otherwise it returns an offset, which is the offset for the total number of unicode names (not an offset for the codeme array per se)
13:58 samcv the name_index array holds the location in the codeme array of every other codepoint which HAS a name in the codeme table
13:58 samcv so the 0th item in the codeme table, is at 0, the 2nd one is at 4
14:30 pyrimidine joined #moarvm
14:33 Ven joined #moarvm
14:47 pyrimidine joined #moarvm
15:01 pyrimidine joined #moarvm
15:16 Ven joined #moarvm
15:41 pyrimidine joined #moarvm
15:42 samcv i gotta go to bed, but I updated the gist, and the repo so it should be basically ready for you to see if you can get working
15:45 pyrimidine joined #moarvm
15:58 domidumont joined #moarvm
16:50 brrt joined #moarvm
16:50 brrt good *, #moarvm
16:51 brokenchicken \o
16:52 jnthn o/
16:54 brrt \o
16:54 brrt so… what i wanted to report about
16:54 brrt is that explaining register allocation is actually really, really hard
16:55 brrt the processs itself isn't, but it requires a lot of assumptions and background about how compilation works in the first place
16:55 brrt so…. i'm meaning to write a blog post about having implemented linear scan, but i find myself unable to explain what i did
16:55 brrt this bothers me
17:00 brokenchicken :)
17:00 brrt maybe i can try here and if it works, i can transform it into a post
17:01 brrt basically; register allocation is all about ensuring that the right values are in the right registers in time for use by the instructions of the program
17:04 brrt there's two trivial ways to do that
17:04 brrt one is to compute and store every value ever in a register
17:05 brrt that is of course not correct for larger programs because the set of available registers is pretty small
17:05 brrt the second is to store-and-load every value ever from memory just before they are used
17:06 brrt that's correct (there is usually enough memory available to do this) but it's very much suboptimal, because a): your bytecode size grows by a bunch for all the load-and-store instructions, and b): memory operations are pretty slow if cached, and disastrously slow if not
17:06 brrt so what you want to do is to find the solution wherein you minimize the number of memory traffic required
17:06 brrt s/number/volume/
17:07 brrt so the first thing you need to know, is which values are necessary when
17:07 brrt and you typicallly have to take flow control into account with that
17:08 brrt i.e. you need to 'deliver' the value that was computing using whatever flow control the programmer has designed
17:09 brrt one of the solutions is to divide the *variables* into a set that you'll store in registesr, and a set that you'll keep in memory
17:10 brrt but that's not very cool either, since it's well possible that different control flow paths use different sets of variables; you might end up having to 'sacrifice' one path for the other
17:11 brrt so the solution to that is to stop looking at variables but just at the values used
17:11 brrt that's achieved by the SSA transformation
17:12 brrt SSA = single static assignment, and it transforms every variable assignment into a declaration-and-assignment of a new variable; it makes variables immutable
17:12 brrt or in other words, it replaces variables with their values
17:12 brrt the expression JIT already does this
17:23 brrt so to find out where a register is required for a value analyze the 'liveness' of program values; the result of this analysis is a 'live range' for every value used
17:25 brrt a live range is basically the set of all instructions (or in our case, things-that-represent-instructions) that either have the value as output (definitions) or as input (uses)
17:25 brrt that set can contain more than one definition - contrary to my earlier statement! - because definitions can be connected using PHI nodes
17:26 brrt and a PHI node is basically something that describes a value defined in two or more different control flow paths
17:27 nine .oO(Memory traffic volume depends not only on how often in the code a memory slot is accessed but also how often that code is run (e.g. loops). So it's gonna be a trade off between local and global optimization)
17:27 brrt that's exactly right :-)
17:27 brrt basically, you have to compute the expected cost of spilling
17:27 brrt decommuting &
17:29 nine .tell brrt so as we're talking about a JIT, do you actually have some information about runtime behavior accessible in the register allocator? I.e. does it have an idea how often loops may run?
17:29 yoleaux2 nine: I'll pass your message to brrt.
18:00 pyrimidine joined #moarvm
18:50 ggoebel joined #moarvm
19:18 zakharyas joined #moarvm
19:23 dogbert17 joined #moarvm
19:26 ggoebel joined #moarvm
20:29 pyrimidine joined #moarvm
21:19 pyrimidine joined #moarvm
21:49 domidumont joined #moarvm
22:08 pyrimidi_ joined #moarvm
22:18 Ven joined #moarvm
22:26 ggoebel joined #moarvm
22:33 MasterDuke samcv: turns out replacing this ( https://github.com/MoarVM/MoarVM/blob/master/src/core/coerce.c#L375-L392 ) with a giant switch statement is 25% slower
22:33 Ven joined #moarvm
22:35 MasterDuke for 1m iterations of nqp::radix() it resulted in 300m more instructions, 250m more branches, 8m more missed branches

| Channels | #moarvm index | Today | | Search | Google Search | Plain-Text | summary