how to get concurrent - model design question

5 views
Skip to first unread message

bOR_

unread,
Feb 26, 2009, 5:56:59 AM2/26/09
to Clojure
Hi all.

First. For those who remember, I posted an individual-based model in
this group some time ago (eden.clj), and got some very helpful replies
on where I misunderstood clojure and did things the hard way. I wanted
to report that that model by now is written purely as nonblocking
agents, and is happily burning cpu cycles as it simulates the
evolution of our immune system :). thanks for that!

Second. I am updating an older model on Chlamydia prevalence in a
dynamic sexual contact network, and implemented it in clojure (http://
clojure.googlegroups.com/web/chlam-clean.clj), based on the model in
this paper (http://aje.oxfordjournals.org/cgi/content/abstract/
144/3/306). It isn't fully equivalent to the model in the paper yet
(for some reason, Chlamydia keeps going extinct), but that is
something I will puzzle over myself. I am however, still somewhat
fuzzy on what a good way is to get the model concurrent.

I tried replacing

(doseq [e [retire-host slowdown-host infect-hosts naturalrecovery-host
pair-host breakup-host] i world]
(e i))))

with

(doseq [e [retire-host slowdown-host infect-hosts naturalrecovery-host
pair-host breakup-host] i world]
(send-off (agent i) e)))

or

(doseq [e [retire-host slowdown-host infect-hosts naturalrecovery-
host pair-host breakup-host] i world]
(send-off (agent nil) (fn [_] (e i))))))

There doesn't seem to be any concurrency happening, and the whole
thing just slows down to not doing much at all. Anyone knows what I am
doing wrong?. Considering that I wrestled with this before in previous
posts in this group, I offer my apologies for not getting the correct
way of mixing agents and refs into my thick skull. (Luckily I have
grasped agents-only models, so there is hope :), but as I need refs in
this model, I'm again banging my head against the wall).


Timothy Pratley

unread,
Feb 26, 2009, 6:59:29 AM2/26/09
to Clojure
Hi Boris,

>  (doseq [e [retire-host slowdown-host infect-hosts naturalrecovery-
> host pair-host breakup-host] i world]
>            (send-off (agent nil) (fn [_] (e i))))))
>
> There doesn't seem to be any concurrency happening, and the whole
> thing just slows down to not doing much at all.

This code will create potentially (count world) threads 10000. Just
using send instead of send-off would possibly speed things up a lot as
it will limit the number of threads. Also creating a new agent every
time just to provide a thread is not economical. You could instead
have a small pool of agents and reuse them. Or you could take
advantage of futures which have been recently added to run the task
without an agent at all:
(doseq [e [r s i n b] i world] (future (e i)))
Also you might consider using (comp) to compose the set of e into one
function, which will reduce the amount of dispatches. Lastly, why do
you say you have to use refs here? It isn't obvious to me from the
code - the world locations look like they could be agents - but I'm
probably missing something, its quite complex :)

Regards,
Tim.

bOR_

unread,
Feb 26, 2009, 8:14:44 AM2/26/09
to Clojure
Thanks for the reply Timothy! I'll look into the future things :).

The main reason for using refs was because I am constructing a contact
network between different refs (a graph, consisting of nodes and
edges.), which changes over time (all the short-term and long-term
relations between hosts being started and breaking down again). If two
of my refs start a steady relation together, I want a guarantee that
one refers to the other in its :steady key, and the other refers to
the one. So it seemed to me that both have to change simultaneously. I
don't want host 1 to start initiating a steady relationship with host
2, while at the same time host 2 is starting one with host 3. I wrote
an earlier version of this model with agents, but couldn't see how to
guarantee bidirectional edges in a concurrent situation.

Timothy Pratley

unread,
Feb 26, 2009, 6:08:03 PM2/26/09
to Clojure
Ah I see, yes that makes sense.
Relationships truly are a contract in this case!
Reply all
Reply to author
Forward
0 new messages