freenode/#sicl - IRC Chatlog
Search
9:24:11
beach
So I ran sb-sprof again, and if I understand the output, the HIR interpreter takes almost all the execution time (99.6%), and interpreting the FUNCALL-INSTRUCTION represents more than 92% of the total time.
9:25:35
beach
This result suggests to me that more inlining could make a big difference. We already inline nested functions when that is determined possible, but we do not inline global functions.
9:33:00
beach
So now I don't think any particular instruction dominates the execution time, and that makes heisig's idea the right one, i.e., optimize the interpretation itself.
9:34:55
beach
Accessing the lexical environment is around 15% of the execution time, and that fraction will likely increase as the instruction execution is made faster.
9:35:46
beach
So turning the hash table into a vector will likely make a big difference, at least later on.
9:39:54
beach
Actually, it looks like accessing the lexical environment represents some 25% of the total time.
9:41:38
beach
I don't know whether version 1 of heisig's HIR evaluator changes the representation of lexical environments. If not, we should see a significant increase in that percentage when his evaluator is used.
9:56:40
jackdaniel
in ttf renderer written by Andy Hefner there was a very specialized "hash table" based on a vector, because gethash was the bottleneck when rendering glyphs. I've extended it to account for pairs of characters to account for kerning.
10:01:10
beach
jackdaniel: Sounds good. But in the case of HIR, it is straightforward to scan the program first, and assign an index to each variable.
10:01:23
jackdaniel
since characters have an index with the upper bound, it is possible to construct hashes directly from the index (or a pair of indexes if we take pairs of glyphs)
10:01:43
jackdaniel
moreover there are no conflicts, so it is just a bit fiddling operation to compute the hash and address of the value
10:33:46
heisig
I made some progress with the HIR evaluator, but haven't solved the issue in boot phase 3, yet.
10:35:03
heisig
The evaluator dies when attempting to throw to sicl-run-time:frame-pointer tag that doesn't exist.
10:36:34
beach
heisig: Before I forget, I wanted to ask you when you plan to graduate. And whether in Germany, it is a good idea to then do a post-doc. If so, if I were you, I would apply to EPITA.
10:38:04
jackdaniel
beach: should I assume, that the class name is a symbol (after the standard and as specified in the clostrum pdf), or that it is an arbitrary lisp object (but still comparable with eql)?
10:39:07
no-defun-allowed
If you have identified the problem, then this doesn't matter: but would it be feasible to write some code to generate random Common Lisp code, then compare what the evaluator does to what the host does? I would guess not, because it wouldn't be hard to accidentally write programs that don't terminate, and there might be a lot to generate, but fuzzing like that usually makes bugs fall out.
10:39:33
beach
jackdaniel: That depends. I think FIND-CLASS and (SETF FIND-CLASS) require it to be a symbol. Whereas :NAME and CLASS-NAME do not.
10:39:52
heisig
beach: I plan to graduate earlier next year. But I am also writing a proposal for further work on Petalisp. If that goes through, I will have a post-doc position in Erlangen.
10:40:46
beach
The reason I suggested that, is that it is sometimes frowned upon to do a post-doc in the same place as the PhD. But that depends on what you want to do later.
10:43:54
jackdaniel
I've noticed that you have mixed ordering - for run time environment protocol functions are listed 1. reader, 2. writer, while in the compilation environment it is the other way around
10:44:11
heisig
no-defun-allowed: Yes, I thought about writing a code fuzzer and comparing the behavior with that of the host. In fact, I already implemented the latter part.
11:13:56
jackdaniel
beach: another question -- is compilation-environment-mixin in 5.3 a typo (a class compilation-environment is defined earlier)?
14:03:33
jackdaniel
beach: I've noticed that you often say "an ordinary function or a generic function", is there an operator (in clostrum), which operates on one but not another? or could the passages be simply replaced with "a function"?
14:14:51
jcowan
An ordinary function isn't quite a generic function with a single method whose signature is t ... -> t, though in a CLOS-first implementation that would be a reasonable implementation strategy. You still need a flag saying "not really generic" so that you can signal an error on any attempt to add another method.
14:16:00
jackdaniel
jcowan: I'm not saying, that "ordinary functions" and "generic functions" are the same, only that both fall into the same category of being a function
14:20:55
beach
jackdaniel: It looks like you can replace the phrase "ordinary function or generic function" by just "function" everywhere.
14:21:50
jackdaniel
I was mostly curious if I'm not missing something by creating a single storage for all "function" definitions
14:22:11
jackdaniel
i.e if there is a need to have two hash tables: ordinary-functions and generic-functions
14:36:35
jackdaniel
strictly speaking, generic-function is a subclass of funcallable-standard-object (which is a subclass of function) afair
14:38:28
jackdaniel
compiled-function -> function <- funcallable-standard-object <- generic-function
16:05:34
jackdaniel
beach: I don't understand the specification of a funciton function-unbound (same applies to variable-unbound) -- if this function always returns a function, which signals undefined-behavior (which is eq for the same name and env), how can the client code be used to determine whether the function-name is unbound?
16:07:52
jackdaniel
right, but it is not clear to me, what is the purpose of this function, and why the passage "client code can use the return value of *this* function to determine whether /function-name/ is unbound"
16:09:47
jackdaniel
also, "when function-name has no definition as a function, the return value of this function is the contents of the cons cell returned by function-cell" -- otherwise what is the return value? freshly consed lambda? then it won't be eq if the function is defined later. I've made a workaround of that by storing the undefined-function lambda in the conse's cdr (so eq is preserved)
16:13:48
beach
Whenever a generic function is called that requires information about some function in the environment, if there is not yet a cons cell to hold the function, then one is created. If the call is to (setf fdefinition) then the cons cell is filled with the function passed as an argument. If not, the cons cell is filled with this function that signals an error.
16:14:34
beach
I guess I included the function-unbound function for clients who want to somehow alter the way the bound-ness is used.
16:15:30
beach
I say, include both of them. It doesn't cost very much. They just return the contents of a slot anyway.
16:16:35
jackdaniel
n.b I've implemented the function-cell (in the "virtual" subsystem) to be filled one called (i.e setf fdefinition does not eagerly create the function cell)
16:17:06
jackdaniel
please do, I think that the specification of the function-unbound is not very clear
16:18:13
beach
I don't understand what "I've implemented the function-cell (in the "virtual" subsystem) to be filled one called (i.e setf fdefinition does not eagerly create the function cell)" means.
16:19:23
beach
Normally, there is typically no information associated with a function name in the environment.
16:20:05
beach
As soon as client code requests some such information, an entry for a function is created (provided answering the request requires such a creation).
16:21:42
beach
Then an entry is created, a CONS cell is created in the entry, and a function is created that signals an error, and that function is stored in the entry and in the cons cell. Finally, the answer to the request is an error, because the function FDEFINITION signals an error if the contents of the CONS cell is EQ to the unbound function.
16:22:07
beach
If then, client code does (setf fdefinition), the cons cell is filled with the argument given.
16:22:29
beach
If, later, the client does fmakunbound, then the special error function is placed in the CONS cell.
16:23:48
beach
If you want to see how it is done, look in the First-class-global-environments directory in SICL.
16:25:08
jackdaniel
I think that implementing it straight from the specification may reveal some issues with it (also, I've implemented some of it already; that lead to this question)
16:25:48
jackdaniel
I will paste the code in a minute, first I want to formulate a next question based on your description above
16:30:14
jackdaniel
what you have described above implies, that you assume, that i.e fdefinition eagerly creates the function cell
16:30:37
jackdaniel
but it is not obvious to me from the specification, before asking the question I did it as pasted above
16:31:20
jackdaniel
i.e (setf fdefinition) would setf an entry in the functions hash-table, but it would not create the cell, the cell will be created only after the first call to function-cell
16:35:38
beach
Yes, fdefinition eagerly creates a function cell, but I don't think it has to be done that way.
16:37:23
beach
I guess you don't HAVE to create the cell, but you might as well, because you need to store the function somewhere.
16:38:50
jackdaniel
(I've added an annotation with (setf fdefinition) method https://plaster.tymoon.eu/view/1974#1975)
16:40:16
jackdaniel
I mean, I was implementing methods from top to bottom, and there was no single place where I had to use funciton-cell (yet), at least as far as function description were going (until I've encountered function-unbound, which description is not clear to me)
16:40:17
beach
You could store the argument to (setf fdefinition) in the function entry, and then copy it to the cell when the cell is asked for, but why the duplication of storage?
16:41:34
beach
I am a bit stressed because dinner is imminent, and I had to connect using a cable which is too short, so I am using the bad built-in keyboard.
16:42:07
beach
So I am reading the code, but I will very likely not understand it before dinner is served.
16:42:48
jackdaniel
function cells in the collection which is used to store functions (and access functions from cells)
16:43:10
jackdaniel
instead of what I did, that is store functions in one collection, and copy them to cells when requested
16:45:01
jackdaniel
you've said, that it is necessary to update function-cell when fdefinition is called, and that surprised me because it was nowhere specified and implementation without doing that works (however not optmially), that's why I have asked
16:47:24
jackdaniel
in light of that, should the specification stipulate that i.e fdefinition updates the function cell? or, if not, how should the specification of function-unbound look like (or should the function be removed)?
17:10:06
jackdaniel
OK, thanks to these missing bits of context now I understand what is the purpose of the function function-unbound. If we specify, that the undefined-function signalling function is stored in the function-cell's cdr, then I think that env:function-unbound is not necessary in the protocol. I'll implement it for now as it is specified.