freenode/#lisp - IRC Chatlog
Search
20:38:31
pjb
sebboh: when the data cannot fit a register, the register contains a pointer to the data instead. It's still good to have the pointer directly accessible in the register, instead of having to read it from memory.
20:42:50
aeth
Does anyone know what the maximum efficient number of values in (values ...) is on typical modern implementations? multiple-values-limit is "not smaller than 20" and in 64-bit SBCL is 4611686018427387903, but I doubt it's as efficient with 4611686018427387903 as it is with 4.
20:44:12
easye
aeth: I think it is mostly about efficiency of space, not time (other than the time it takes to construct a gadzillion VALUES to return in the first place)
20:45:55
jackdaniel
if it's small number (say - 2), it might be quite beneficial to store it in registers if you have control over them
20:47:03
aeth
Well, I'll be specific. With 3 or 4 values, it's (usually?) better just to work with values directly than to create a temporary array to represent a 3D vector or a quaternion. What about e.g. the 16 values of a 4x4 matrix?
20:47:50
aeth
There has to be some point, especially in SBCL's 4611686018427387903, where an array (not a list!) beats multiple values, right?
20:48:46
aeth
The alternative here would be an array declared dynamic extent, which at least for size 4 produces different (larger) disassembly than values
20:49:22
jackdaniel
aeth: do you have actual application where you have to optimize such case, or it's just what-if in a vain?
20:49:46
jackdaniel
because unless it's indeed a bottleneck I'd say - choose whatever fits your semantics best
20:50:00
aeth
jackdaniel: Yes, I'm writing a 3D game engine. There are lots of temporary vectors and quaternions.
20:50:45
aeth
It is at least looking like multiple values for sizes 3 and 4 beat specialized arrays of sizes 3 and 4 declared dynamic-extent.
20:52:17
aeth
jackdaniel: #lispgames is more about higher level game design than the finer details of Common Lisp performance.
20:52:39
aeth
And I suspect what most people know about CL performance in #lispgames is for SBCL and maybe CCL or ECL, not modern implementations in general.
20:53:14
aeth
I have been optimizing SBCL and CCL, halved their CPU usage, now they're mostly < 3% CPU, but I can't get 60 FPS in ECL for some reason.
20:54:01
aeth
I only use objects before the game loop (rather than during), and for the game window object.
20:54:49
jackdaniel
either way many people there know a lot about optimizations, they do write 3d engines after all
20:55:24
aeth
I have exactly one method remaining in my code, apparently. It is run before the game loop.
20:55:59
aeth
I do use type declarations extensively. Could that hurt performance in ECL even though it helps it in SBCL and CCL?
20:57:08
aeth
jackdaniel: I mostly profile in SBCL because it's so much easier to profile with. I can't even use disassemble in ECL, apparently.
20:57:33
aeth
It's possible that there's a bug in cl-opengl or cl-sdl2 that hurts performance only in ECL.
20:59:44
jackdaniel
either way I don't think your bottleneck lies in returning multiple values from function
21:00:55
aeth
Well, I have eliminated almost all consing in SBCL (it's easier to do it there than in the others... I'll attempt CCL at some point)
21:22:34
Bike
but yeah, for (sb-profile:profile ..names...) ...whatever... (sb-profile:report) you just do (with-monitoring (...names...) ...whatever...) i think.
21:32:21
aeth
It takes 0.025519 seconds per call in ECL and (/ 60f0) => 0.016666668... so that right there is going to blow the 1/60 of a second budget
21:33:48
TeMPOraL
jackdaniel: oh, so you updated a portable profiler; should have googled harder before writing my own for the game engine... xD
21:34:18
aeth
It's 0.000084 in CCL and 0.000061 in SBCL, so i's several orders of magnitude slower in ECL.
21:37:28
TeMPOraL
ACTION is reminded of that time on VM where ~90% of my game time was spent on ioctl...
21:39:06
aeth
Oh, I forgot, I no longer inline draw, so I can profile the per-entity draw function instead of the iterate-over-every-entity render function.
21:39:56
aeth
It doesn't help that ECL apparently doesn't measure consing. I know it's lying when it says 0 consing in monitor:report-monitoring, because two functions I was checking definitely still do some consing, including the render one
21:40:54
Bike
assuming you got the new metering, it should work, especially since jackdaniel also maintains ecl
21:41:17
aeth
It looks like each draw call takes 0.002299 seconds, or about 14% of the time I have to do literally everything.
21:42:27
TeMPOraL
gonna take a wild guess here; my problem was caused by glGetError being expensive; maybe try recompiling cl-opengl with #+cl-opengl-no-check-error ;)
21:43:18
aeth
I've optimized far more than I probably should at this point, in part because ECL can't hit 60 FPS
21:44:37
aeth
(And I have an i7-4790k. If I can't hit 60 FPS due to single-threaded CPU usage, then only an i3-7350k and an i7-7700k could possibly hit 60 FPS)
21:50:46
aeth
What surprises me, though, is that ECL is so much less efficient here than SBCL and CCL, though. e.g. I'm getting 0.000009 sec/call in CCL and SBCL... so ECL is 255x slower...
21:50:55
aeth
And this is a function that's interfacing with C, which I thought ECL was designed for.
21:51:28
aeth
It's possible that there's a bug in cl-opengl, or it's possible that there's consing that's not a big deal in SBCL and CCL, but is in ECL.
21:52:01
pjb
It's not surprising since it goes thru a C compiler. C compilers cannot generate efficient code, since they lose so much information about the source!
21:57:59
aeth
It does make a lot of sense that SBCL performs identically to CCL here... since they are calling the same C. I'm baffled for the 255x increase in ECL (and I wonder if 255.4444 is a coincidence since 255 is a suspiciously round number)
21:58:29
sausages
aeth: i wonder if maybe there's implicit overhead to foreign function calls in ECL that are just slower than in CCL/SBCL? does it have to box or otherwise process a float every single time it passes a float to a GL call?
21:59:18
aeth
sausages: By the time I get to the draw function, the floats are already in foreign data structures. I cache the matrices that I feed to GL.
21:59:44
pjb
aeth: no, but the code it generates is bound to be slower than the code sbcl generates.
21:59:58
aeth
(I only change the foreign matrices when the entity changes. This can lead to interesting bugs if I forget to set the dirty bit.)
22:00:38
aeth
I think what I should try to do next is finish removing the consing from the draw function, and then see if the slowness remains in ECL.
22:02:14
sausages
if there's any lambda functions being used in draw, maybe split 'em away into dedicated functions, just in case the profiler might overlook or not-report anonymous functions
22:10:13
aeth
I am just reading in values from a CL struct and from the cached foreign matrices and feeding them into gl or %gl functions. I'm actually not even sure where it conses.
22:10:34
aeth
Of course, now I'm not measuring any consing in draw in SBCL. Perhaps I misremembered it and was thinking of render-entities.
22:27:11
easye
S3 wuz kinda tardy for me ~three hours ago. Wonder if it was AMZN adjusting its buckets...
23:41:05
borei
i have question - functions and macroses (just started to work with macroses, and don't have enough greep on them), but any way - what would be rule of thumb what to use ? from my 2 months experience but approaches can be used to solve my tasks.
23:42:09
White_Flame
if you know for sure that you've got some repetition, or you want to automatically generate code from a custom spec, then go with macros
23:45:36
aeth
Macros generally should fit basic patterns like define-foo, do-foo, with-foo, etc. Sometimes macros help you write common macros, e.g. define-modify-macro for incf-style macros.
23:47:44
borei
to find distance between 2 points in 3D space - should it be macros of function, mybe my question is absolutely incorrect
23:48:50
aeth
If you're concerned about it being so trivially small put this above the defun: (declaim (inline foo)) where foo is the function name.
23:50:10
aeth
Inlining will, as a rule of thumb, really help with functions that deal with numbers and specialized arrays if the calling function knows the types.
23:52:43
krator44
i've looked at some example code and basically.. like i thought embedding using ecl will be less work than the other way around using cffi
23:55:18
aeth
Macros as an optimization aren't as good as inlining, but type declarations might be better than any macro-style thing. But, either way, use functions where you can.
0:00:11
krator44
i'm actually looking at the most reliable way thats why i'm thinking of embedding CL into C++ (as a scripting language)
0:01:03
axion
White_Flame: Haven't heard from him in a while, and I was mistaken to think that his Github activity has stalled...only Clasp
0:01:09
White_Flame
krator44: depends on if you ever want to deal with C++-isms across that boundary
0:04:58
krator44
i'm gonna provide a well-defined io for the lisp program which will deal with the hardware not at all
0:08:12
krator44
the other way is to build a cffi library for cl to link against (or use an existing one)
0:14:12
White_Flame
any FFI is going to have you writing some amount of boilerplate to write & maintain
0:14:37
White_Flame
so I don't see the various options as being all that different in terms of "reliable"
0:18:55
drmeister
krator44: Clasp is A CL written in C++ and designed to interoperate with C++ on every level.
0:22:49
drmeister
It's designed to work with exception handling, classes, virtual functions - all that.
2:26:49
phf
hello, is there a lisp interpreter similar to siod or tinyscheme but with semantics closer to common lisp? i.e. an naive interpreter in a couple of hundred lines of readable c, where whatever functionality is available, it behaves closer to common lisp standard
2:28:07
ben_vulpes
is there some obvious thing i'm missing as to why a handler-bind around a generic method implementation would fail to catch the signaled error or condition?
2:28:36
Bike
it probably does not handle the condition. if your handler doesn't transfer control, the error will just continue up.
2:32:16
ben_vulpes
Bike: thing is, same exact handler-bind /inside/ the generic function handles the condition
2:56:08
emaczen
How would I handle the equivalent of a ccl:no-applicable-method-exists when using a different compiler? Does there exist another condition type? nothing jumped out at me.
3:05:42
borei
just to make sure, when i add object to hashtable (or probably in any collection object) lisp will NOT create new object - is it true statement ?
3:16:41
pillton
borei: The only instances which can be implicitly copied are instances of numbers and characters.
3:17:29
didi
Bike: Hum. I need to write the message onto the paste too. I feel I don't understand the problem properly so I can be succinct.
5:34:08
jackdaniel
krator44: ecl works fine when embedded in cxx application, you have to compile it with -with-cxx flag
5:52:25
John[Lisbeth]
(if common-lisp-has-lexical-scoping nil (query-channel "How do I do lexical scoping with setf in common lisp"))
5:57:23
pjb
John[Lisbeth]: that's the point! You don't! This is why you're told not to use setf to create new variables! Use LET!