The single thread at a time rule is implemented by the transducing context (transduce, into, core.async, etc). Inside of a transducer's implementation you just have to make the assumption that it's being used properly. volatile! is what ensures that there's a memory barrier.
On Tue, Apr 11, 2017 at 2:46 AM, Léo Noel <[email protected]> wrote: > Thank you Alex for these precisions. > > >> The JVM is pretty good at minimizing this stuff - so while you are stating >> these barriers are redundant and are implying that's an issue, it would not >> surprise me if the JVM is able to reduce or eliminate the impacts of that. >> At the very least, it's too difficult to reason about without a real perf >> test and numbers. > > >> Fast wrong results are still wrong. I do not think it's at all obvious how >> this affects performance without running some benchmarks. Volatiles do not >> require flushing values to all cores or anything like that. They just define >> constraints - the JVM is very good at optimizing these kinds of things. It >> would not surprise me if an uncontended thread-contained volatile could be >> very fast (for the single-threaded transducer case) or that a volatile under >> a lock would be no worse than the lock by itself. > > > I agree that the perf argument is weak. > > >> A transducer can assume it will be invoked by no more than one thread at a >> time > > > Fine. Even simpler like this. > > >> Transducers should ensure stateful changes guarantee visibility. That is: >> you should not make assumptions about external memory barriers. > > > How do you enforce no more than one thread at a time without setting a > memory barrier ? > For the JMM, no more than one thread at a time means exactly that return of > step n will *happen-before* the call to step n+1. > This implies that what was visible to the thread performing step n will be > visible to the thread performing the step n+1, including all memory writes > performed during step n inside stateful transducers. > https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html > Still no need for extra synchronization. > > >> You're conflating the stateful values inside the transducer with the state >> returned by and passed into a transducer. That's a linkage that does not >> necessarily exist. > > > What do you mean ? How could a function return a value without having > executed its body ? > > > On Monday, April 10, 2017 at 9:51:30 PM UTC+2, Alexander Gunnarson wrote: >> >> Thanks for clearing all of that up Alex! Very helpful. >> >> On Monday, April 10, 2017 at 3:46:45 PM UTC-4, Alex Miller wrote: >>> >>> >>> >>> On Monday, April 10, 2017 at 2:25:48 PM UTC-5, Alexander Gunnarson wrote: >>>> >>>> I think you present a key question: what assumptions can a transducer >>>> make? We know the standard ones, but what of memory barriers? >>> >>> >>> Transducers should ensure stateful changes guarantee visibility. That is: >>> you should not make assumptions about external memory barriers. >>> >>>> >>>> Based on the current implementation, in terms of concurrency, it seems >>>> to make (inconsistent — see also `partition-by`) guarantees that sequential >>>> writes and reads will be consistent, no matter what thread does the reads >>>> or >>>> writes. Concurrent writes are not supported. But should sequential >>>> multi-threaded reads/writes be supported? >>> >>> >>> Yes. core.async channel transducers already do this. >>> >>>> >>>> This is a question best left to Alex but I think I already know the >>>> answer based on his conversation with Rich: it's part of the contract. >>>> >>>> I think another key question is, is the channel lock memory barrier part >>>> of the contract of a core.async channel implementation? >>> >>> >>> Yes, but other transducing processes may exist either in core in the >>> future or in external libs. >>> >>>> >>>> If not, volatiles will be necessary in that context if the memory >>>> barrier is ever taken away, and it would make sense that volatiles are used >>>> in transducers "just in case" specifically for that use case. But if the >>>> channel lock memory barrier is part of the contract and not just an >>>> implementation detail, then I'm not certain that it's very useful at all >>>> for >>>> transducers to provide a guarantee of safe sequential multi-threaded >>>> reads/writes. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to a topic in the > Google Groups "Clojure" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojure/VQj0E9TJWYY/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
