freenode/#sbcl - IRC Chatlog
Search
18:51:25
aeth
ARRAY-ROW-OF-2-ROW-2-COPY is now 99 bytes with two bounds checks. It was 157 with 4 in 1.4.9. ZOMBIE-RAPTOR:UPDATE-INPUT-MOVEMENT! now has four bounds checks instead of 8.
18:51:43
aeth
So it looks like half of the bounds checks that could have been removed that weren't are now removed.
19:10:44
aeth
What's expected is just 4 more asm instructions in array-row-of-2-row-2-copy than in array-of-2-copy (turning the 2D index into a 1D index?) and I think that's the most useful test.
19:14:49
aeth
Actually, I wonder if those instructions could be removed when the aref is constant on a known-size array. I suspect that they were the main factor in a 4x4 matrix as an array of (16) beating a 4x4 matrix as an array of (4 4) in a matrix* benchmark I wrote a while back.
23:29:16
aeth
The bounds checks are also gone in update-input-movement! which is no surprise because my test case was just a simplification of what's going on there.
23:30:32
aeth
There's one more weird type check that is going on in that function. Inline functions now keep their declarations, which is awesome (especially when (speed 3) affects what's going on significantly, like with trig). Probably for a year or two at this point.
23:31:56
aeth
Well, perhaps there was a temporary regression in a version I used for a long time, then.
23:34:54
aeth
I do know at one point the types weren't checked in inline functions with type declarations and now they are. I also think that the (declare (optimize (speed 3))) version of trig functions (staying as single float) didn't stick when using an inline function at one point because I made a note in source that's no longer accurate.
23:35:49
stassats
well, it's actually harder to get rid of inlined declarations than to preserve them
23:37:21
aeth
I would have to find a really old version of SBCL to try to reproduce it (probably 1.2.6 or so) and it wouldn't be worth it since I don't see it anymore.
23:38:51
aeth
Anyway, I use these really simple inline functions to turn a fixnum into a set of 1/0 values using bit logic operations. https://gitlab.com/zombie-raptor/zombie-raptor/blob/8b7ee7a971ceb524138853a64630779cc41289bf/math/boolean-set.lisp
23:40:51
aeth
Well, this test case does *NOT* confirm it. It does manage to remove the type check here. (defun foo (x) (declare ((mod 1234) x)) (boolean-set-union 0 x))
23:41:09
aeth
But I basically have a number that's declared or known to be a subset of (unsigned-byte 60) and it still checks for it
23:41:44
aeth
It's possible that it's because I define the type like this: (deftype entity-id () `(mod ,+max-entities+))
23:42:05
aeth
hmm, so this still removes the check. (defun foo (x) (declare (entity-id x)) (boolean-set-union 0 x))
23:48:20
aeth
I did exactly what I did with the bounds checking issue and took the function, removed everything irrelevant, expanded all of the macros, etc., and I get (defun foo (entity-id) (declare (entity-id entity-id)) (let ((id entity-id)) (boolean-set-subset-p 36 id)))
23:50:41
specbot
upgraded-array-element-type: http://www.lispworks.com/reference/HyperSpec/Body/f_upgr_1.htm
23:52:15
aeth
I guess I should just use (unsigned-byte 64)s because 64-bit implementations will generally have them.
23:53:07
aeth
It's declared as an (unsigned-byte 60) array, but that rounds to 62, and so the compiler is actually better now than when I wrote it, because I don't recall it checking when I wrote it years ago.
23:55:17
aeth
I create it through a macro that also creates a constructor so I can just do a type-of. (type-of (make-entity-set-array)) => (simple-array (unsigned-byte 62) (2500))
23:57:47
aeth
stassats: It's only ever accessed indirectly, through a macro. It's basically just a bunch of bits that makes sure that the query about the entity is valid before completing the symbol-macrolet bindings. So the type of the array should always be known when it's being accessed.
23:58:50
aeth
Using (unsigned-byte 64) might destroy performance on other implementations, though. It's called a lot.
0:00:21
aeth
The way the bits work is if you request velocity, it will either iterate over every entity that has a velocity OR it will (if you requested a specific ID) execute iff the requested entity ID implements velocity.
0:00:58
aeth
There really aren't other implementations where I can know as much about what's going on as with SBCL.
0:07:10
aeth
I should probably do that just to be safe even though I don't think it leaves a function anywhere
0:10:44
aeth
It probably doesn't need to be more than 62. If it did, it would probably need to be significantly more than 62, and I could just combine 2 to 4 of them together. Each bit represents one thing so I don't think that approach would have issues. No need for integer 1 to know about integer 2.