libera/#commonlisp - IRC Chatlog
Search
14:25:42
hexology
maybe i'll ask on stackoverflow, i doubt i'm the only person to struggle w/ things like this
18:58:54
hexology
i have a variable (type (integer 0 *) n) and i'm calling (incf x) but i keep getting compiler notes that sbcl is unable to "open-code float conversion in mixed numeric operation" because it apparently doesn't understand the type of the `1` in (+ 1 n). i have tried all manner of contortions like (+ (the (integer * 0) 1) n) but i keep getting the same compiler note. if only for my understanding: what the heck is going on here, and how do i convince
19:00:48
Bike
the notes are kind of dumb sometimes. what sbcl does is try every possible transformation it knows for (+ a b) and tells you if they don't apply. and that includes the float ones.
19:01:22
Bike
but yeah the problem with optimizing that is that sbcl can't do much with just (integer 0 *) in that circumstance.
19:02:40
hexology
Bike: i see, so it's telling me everything it tried along the way, not necessarily that it ultimately found nothing?
19:03:10
hexology
i don't know why it's even trying to "open-code a float conversion", i'm just working with ints in this case
19:03:46
Bike
like i said, it's trying every possible way to get rid of a call to +. you can see it messing around with complexes too
19:04:50
Bike
it sees (+ 1 n) and goes, okay, can i make this into (internal::float+ (float 1) n)? no, because n isn't a float. i'd better tell the user this in case they could declare n to be a float
19:06:53
Bike
which in this case is obviously (to you and i) not going to happen, but sbcl is not smart enough to realize that since you declared the thing to be an integer, you're probably not going to want it to be a float
19:07:20
hexology
i see. i guess that means sbcl not have some fancy optimized operation for incrementing an integer? (it probably is not important for performance anyway, in this code)
19:08:04
Bike
that means it could be a bignum, which is a big ol multiprecision integer in memory that can't really be dealt with very quickly
19:08:28
Bike
if it knew n could fit in a machine word, like a fixnum, it would just do a machine addition, but it doesn't, so it won't
19:09:11
hexology
hm. fwiw i get the same compiler notes if i declare it to be fixnum rather than (integer 0 *)
19:11:20
Bike
you mean doing (type fixnum n-blank), not just using the? right. i think what happens there is that sbcl doesn't believe you, i.e. doesn't believe that (+ n-blank 1) will always be a fixnum
19:11:36
Bike
because if it _did_ believe you, and you were mistaken, your program would crash badly
19:13:22
Bike
if it wrapped around to 0 that could be very weird for your program, since that's violating what + usually does
19:13:45
Bike
however if you tell it to wrap, like by doing (mod (+ 1 n-blank) ...), that's another story
19:17:01
hexology
i see. i agree that implicitly wrapping around isn't good (and isn't what i want), but 99.999% of the time this value will actually be in fixnum range. i was about to ask, is there a standard way to handle this? like creating a bignum variable but setting it aside unless you are in danger of overflowing?
19:18:51
White_Flame
handle what? the default case handles the 0.001% of the time where bignums are needed
19:18:53
Bike
honestly what most people do is just make it use fixnum arithmetic anyway, which on 64 bit sbcl will go just dandy up until you give it a file with four quintillion lines
19:19:32
Bike
in your particular case, i might just remove the type declaration, since i expect fixnum arithmetic is the least of your problems here optimization wise
19:26:12
hexology
but for the sake of the exercise, how do i convince it that i definitely want to use fixnum arithmetic and that i don't care what happens if i overflow?
19:28:27
White_Flame
if you declared a var fixnum, and then INCF'd it, then with safety off would probably just do fixnum math
19:29:38
Bike
the implementation is indeed free to blow up if THE is violated, but that would be rude of it, and i think sbcl checks THEs except on low safety
19:29:42
hexology
(setq n-blank (the fixnum (+ (the fixnum 1) n-blank))) like this? i hadn't tried that, but i get the same compiler notes if i do that
19:29:49
Bike
although i guess it just compile it to use fixnum arithmetic and then cheeck for overflow
19:31:51
hexology
aha, this worked, thank you: (setq n-blank (the fixnum (+ 1 (the fixnum n-blank))))
19:38:57
pjb
hexology: (setq n-blank (if (< n-blank most-positive-fixnum) (the fixnum (+ 1 (the (integer 0 #.(1- most-positive-fixnum)) n-blank))) (the integer (1+ the integer n-blank)))))
19:44:00
hexology
does it matter if you write (< n-blank most-positive-fixnum) or (< n-blank #.most-positive-fixnum) ?
19:45:31
Bike
The latter means the reader looks up the value of most-positive-fixnum and sticks that in instead of the symbol
19:45:58
Bike
but even the very basic compiler i wrote in four hours the other day is smart enough to compile constants as constants, so don't worry about it
19:46:03
aeth
White_Flame: what about an implementation that allows for compatibility of its compiled fasls between versions? And the version changes the constant.
19:46:38
pjb
hexology: but THE doesn't evaluate the type specifier! So it must be composed at read-time.
19:49:08
aeth
9 times out of ten when I use #. I later get rid of it with a deftype, a defmacro, etc.
19:52:49
jcowan
There are two possible interpretations of declarations: "I declare that this value is a fixnum even if sometimes it isn't, and I allow you to send me straight to Hell if it isn't" and "I declare that this is value is a fixnum, and if it isn't, I want you to signal a condition."
19:54:18
Bike
sbcl also offers "i declare that this is a fixnum and i'd appreciate if you checked but like don't worry too much man"
19:55:49
Bike
i would also like to implement "I declare that this is a fixnum and if you actually use that information signal a condition, but otherwise who cares" but that's pretty involved to do
19:58:30
aeth
I think it comes down to there being two kinds of types (at least in CL): types-for-reliability and types-for-performance
20:00:10
Bike
sbcl documents what it does in its manual, or do you mean like, a general introduction to how compilers can use these kinds of types
20:00:10
hexology
and again, i'm sure this is not a bottleneck in most applications unless it's some kind of numerical simulation that doesn't call out to some foreign routine
20:00:49
White_Flame
a lot of my microptimization is eliminating function calls and taking advantage of tail calls
20:01:10
hexology
i've skimmed this https://www.sbcl.org/manual/index.html#Handling-of-Types but maybe i need to peruse deeply instead
20:14:09
aeth
and the type declarations would mostly be single-float/double-float, with any difficulty being around the boxing of the double-float
20:21:02
aeth
hexology, when referring to THE and the type system, said "unless it's some kind of numerical simulation that doesn't call out to some foreign routine" then type declarations likely won't be the bottleneck
20:21:56
aeth
but a numerical simulation is likely going to use floating point, which is going to be way easier to deal with in the type system than integers, which have to stay within the defined range (x + y will always stay a float, but won't always stay in the defined integer range)
20:22:11
aeth
with the added caveat that turning off float traps is probably as important as declaring the type
20:27:46
NotThatRPG
jcowan: I believe that the spec only makes the first of the two interpretations canonical, but I also believe it leaves the way open for implementations to use the second.
20:29:21
jcowan
It says the consequences are undefined, which certainly *allows* a condition to be signaled.
20:30:28
jcowan
Of course, with NaN-boxing there is no need to unbox double-floats, as they are already unboxed.
20:35:59
hexology
re: floats, i'm running into a similar issue with sbcl not being convinced that in my *particular* case, my input to sqrt is always positive and so should sqrt should always return a real number
20:36:24
hexology
so i definitely think there's something worth writing about here, if there's expert knowledge to be written down
20:42:59
Bike
i mean, you can compile the code in different ways if the compiler is allowed to make some assumptions about the floating point environment, but that's not quite the same
20:43:24
Bike
hexology: i'm not sure what there would be to write down there beyond that you'll have to declare the input positive... what's going on?
20:45:21
Bike
i have some personal notes on CL arithmetic optimization strategies for my own purposes, but they're pretty sparse and not really directed at programmers
22:36:45
Lycurgus
in looking for a state machine thing in cl, i couldn seem to do better than cl-monad-macros
0:13:57
resttime
Bike: Asked in #sbcl about my add-vop and your answer seemed to be it. (move r x) (inst add r y) in the generator works as expected
0:44:44
Bike
ah, well there you go then. a little surprising it doesn't move them itself, it looks like the parent vop has stuff for indicating that
0:52:36
akoana
hmm, what's happening here: https://termbin.com/71e4, with (let ((prod 1))...) I'm getting a big number, with (let ((prod 1.0))...) it works as expected, strange
0:59:44
hayley
I wouldn't be surprised if you got a ratio with very large components, but the actual value is quite small.
1:03:12
akoana
sorry the 2n stuff is a remnant of previous experiments, here a cleaned up version + results: https://termbin.com/b9a4
1:05:28
akoana
I did the tests with 100000 iterations in emacs before, so I gave up looking at the result :)
1:08:05
akoana
Bike, hayley: Thank you very much - I was about losing my confidence in lisp - you have saved my soul