3 ms·
Does OCaml not already support multicore? Is concurrency green thread based? Even at that, there's nothing stopping a user from starting multiple processes....
by j_baker 11y ago
Does OCaml not already support multicore? Is concurrency green thread based? Even at that, there's nothing stopping a user from starting multiple processes....
- bad_user 11y agoStarting multiple processes sucks though, you know, for the kind of use cases for which OCaml should be well suited for. This is because OS processes are more expensive than threads and communication and synchronization between such processes gets very expensive.
- istvan__ 11y agoon this argument you could state that Erlang's processes the way to go because OS threads are way more expensive. If I have a problem that I can easily make parallel than I could just start up N OCaml processes and send each process a chunk of work and this would not be much more inefficient than the thread based implementation. On the top of that, I don't like to create a tonn of threads in any application, I much rather have a fixed number of threads and using channels to send them work than dynamically (on demand) creating threads or processes.
- bad_user 11y agoErlang's processes are actually better than threads for many use cases, yes. But the thing is that with 1:1 multi-threading you can build many abstractions on top and for example on top of the JVM frameworks using Erlang's model like Akka [1] and Quasar [2] are very popular. Either way, you can't compare Erlang with platforms whose notion of parallelism involves POSIX's fork, but lo and behold, I'm comparing it with Java because I can. MOST problems are not easily parallelizable and you'll end up with concurrency. Concurrency means synchronizing and sending messages between processes. For example sending messages between processes means opening a socket of some sort, serializing the data you want to send and deserializing it on the consumer's side. That's extremely inneficient and there's no way you can end up with a pipeline of tens of millions of messages per second, but with 1:1 multi-threading you can [3]. Erlang can't cope with this load btw. One other thing I like about working with threads is the user-friendliness. Yes, skipping over the perils of multi-threading which you can sort of avoid by using better libraries, you can easily do things like number crunching using "parallel collections", combine actors with reactive streams and futures, or fake asynchronous I/O by blocking threads. People nowadays tend to underestimate the utility of blocking threads, but it's pretty cool having an interface like `def fetchData: Future[Result]` that could be implemented on top of Netty (asynchronous I/O) or with JBDC (blocking I/O), only suffer a very small penalty and your process to still be able to reach 80% of CPU utilization. So I think OCaml getting multi-threading support is a pretty big deal. [1] http://akka.io/ http://akka.io/ [2] https://github.com/puniverse/quasar https://github.com/puniverse/quasar [3] https://lmax-exchange.github.io/disruptor/ https://lmax-exchange.github.io/disruptor/
- istvan__ 11y agoThanks. I think Erlang is the grandfather of languages using the actor pattern and at the same time Joe realized that POSIX threads does not belong to business logic code and it can be done without leaking the number of actual OS threads to the user's codebase. On the top of that Joe also implemented the message passing to avoid the shared memory that is a serious problem from the safety point of view for applications with threads. One thread can take down the entire process execution. Addressing these in Erlang made it possible to write the first commercial system with extra high availability and fault tolerance. JVM is obviously great a VM, and Scala brings most of the Erlang (and many other languages) features to the table. I am not sure about the fault tolerance. I need to look into how Akka implements the actors. > Concurrency means synchronizing and sending messages between > processes. I think in Erlang you can do only async sending and when the receiving process wakes up it gets it through one of the means you mentioned. http://bartoszmilewski.com/2009/02/10/message-passing-sync-or-async/ http://bartoszmilewski.com/2009/02/10/message-passing-sync-o... > Erlang can't cope with this load btw. This is what I am curious about. I have seen only one big system written in Erlang that was massive big. WhatsApp was also running in Erlang and they achieved something like 1M connection/server. That was impressive. I am wondering how could you do that with Akka? > https://github.com/puniverse/quasar https://github.com/puniverse/quasar I am following the development of these, starting to use it in Clojure soon, I am curious how it works out. Personally I prefer Aleph on the JVM for Clojure projects but wanna see what is happening in Quasar & co. https://github.com/ztellman/aleph https://github.com/ztellman/aleph
- murbard2 11y agoYes, the threads are green threads: only one can run at a time. There's also an Async framework in Jane Street's Core library and there's LWT. My understanding is that GC is hard with multithread, particularly in a functional language where it's going to do some heavy lifting and needs to be very performant.
- Refefer 11y agoThat's not really true. Erlang's VM is fantastic at GC with thousands upon thousands of green processes multiplexed onto the system threads, allowing soft realtime performance. Similarly, Haskell's Parallel Strategies library works well with the Parallel GC. Immutability makes this a whole lot easier. Or were you referring to OCaml in particular?
- murbard2 11y agoTo OCaml in particular, and you're right that immutability does make it much easier, but OCaml has mutable variables, which is precisely why it's hard.
- tormeh 11y agoErlang uses only actors as concurrency mechanism and exploits that fact by giving each actor its own heap. So Erlang's GC does not need to accommodate concurrency, even though Erlang itself does.
- bad_user 11y agoGC can be hard with single threading as well. Even if you don't have concurrency to worry about, it still has to be incremental - meaning to do its work in small batches and provide a guarantee that the process doesn't get blocked for more than X millis. Also, if you can rely on the data-structures stored in your heap to be persistent, then you can tune the GC for it. The problem is that you need to make assumptions about the life-cycle of those data-structures. For example, the persistent data-structures being used in Scala or Clojure can be pretty heavy for the JVM's garbage collectors because they tend to produce junk that is neither short-term or long-term, thus invalidating the assumptions with which the JVM was built with. And generally that's OK, because the JVM's GCs can cope pretty well and if the need to optimize arises, well both Scala and Clojure are hybrids (just like OCaml), so you can just use mutable stuff if by profiling you see problems. So the theory is known and a decent concurrent GC can be built.