libera/#sicl - IRC Chatlog
Search
9:23:28
moon-child
if doing a lot of fences, you should stay in the read-barrier code pretty much all the time (and maybe the minor gc has some heuristic to not switch back then), so you don't pay so many return mispredicts
9:25:18
hayley
I probably should see what the Sapphire people did. The paper only mentions non-volatile and volatile fields in Java, and nothing on other sorts of atomic access.
9:33:09
hayley
Maybe the issue could be avoided by making sure a mutator flips its roots to newspace, before fencing. But that doesn't help us at all, as we are trying very hard to not flip roots.
9:57:16
hayley
My wild guess at the moment is that the read barrier is only necessary when performing atomic updates, but I have no idea.
10:01:09
hayley
But then something like (let ((x 'old)) (atomically-setf x 'new) x) could return either OLD or NEW in the resulting memory model, which is pretty weird.
10:20:43
hayley
...no it couldn't, what am I saying? One "issue" occurs when a replicated write occurs concurrently with two unsynchronised reads to either replica, and the reads read both the old and new value. But this is fine, as the write can be observed to happen in between reads.
10:24:57
hayley
Another issue occurs when two threads try to perform replicated writes concurrently, in which case the replicas can remain out of sync indefinitely. I think we could get away with locking, if the critical section is only two writes, and the locks have fine granularity (say, one lock bit per 64 bytes, for arbitrary values of 64). A similar thing applies for atomic updates (though, if the user wants lock-free updates, it might be nice to give them
10:29:13
hayley
And, of course, if we spend too much time locking while performing replicated writes, we can cut our losses and just do a minor GC/promotion. Though the first issue might be a real issue, if we observe the new value, and then the old value again, by reading replicas in the opposite order to which they were written. The memory model would likely allow reordering, but not across a fence, which is the real problem here.
10:49:38
hayley
I have a vague idea, but so far there isn't a chance this idea can be done efficiently. It might suffice for a fence to ensure that all locks have been released, i.e. there are no replicated writes occuring concurrently with the fence. Therefore it is not possible for reads occurring after the fence to miss any writes which occurred before the fence, I think.
10:50:45
hayley
Though, again, replication copying is hopefully uncommon and required of very few objects, so a fence might just require iterating over a table of replicated objects, if there are any replicated objects to deal with.
11:09:39
hayley
That would look like thread-local heaps for mutable objects, without having to fix every root when the write barrier is tripped. We only had to invent our own replica coherency protocol in software.
12:10:55
hayley
Perhaps this scheme is too slow in practise; I have no idea and would have to test. Speculative lock elision could be useful, if we get a working implementation in the rest of this century. And we can still decide to avoid local allocation or stomach a minor GC if the time overhead of replication is intolerable.
13:28:32
scymtym
beach: i have already written down some requirements for the environment library. i can try to make those available but i'm not sure whether i will manage to do it today
13:29:22
beach
Great! No rush. I decided Clostrum is good enough for me to continue working on bootstrapping, so I won't work on it for a while.
15:05:36
contrapunctus
scymtym: «I've been using `eclector.parse-result:read` to read forms in files; but I can't figure out how to get skipped input (specifically comments), or even its location. I've been trying out different things based on the manual (defining a `make-skipped-input-result` method, trying to access the second return value of `read`), but to no avail...»
15:20:39
scymtym
contrapunctus: https://techfak.de/~jmoringe/wad.lisp shows how to do that (the example was a test for second climacs originally). you should probably change the body of the MAKE-SKIPPED-INPUT-RESULT method to :reason reason :children '(). you can remove the code using utilities.print-tree or quickload that system, i think. the extra return value you mentioned is relevant for "top-level" skipped input since the corresponding results
19:32:01
moon-child
first atomically exchange the new value with the old one, in the global replica. Then cas it into the nursery replica
19:35:14
moon-child
if a fence has to move everything that's replicated, that's still a win over doing it eagerly; tackle n objects at a time instead of 1. And if you have some atomic-heavy code with a bunch of conses, a bunch of pointing to those new conses from the global heap, and a bunch of fences, the pre-tenurer should learn about that pretty quickly
19:40:38
moon-child
hmm. If you include a generation number, then you don't need a cas loop, just one cas. But you bloat your objects, and have to fight over the generation number, so maybe it's a wash
21:22:08
hayley
@[moon-child]: I don't think a fence has to fix anything, it just has to ensure that there are no replicated writes happening. If we are going lock-free we could use a counter of writes being performed, perhaps.