Simulation with Erlang
Wed Dec 13 09:43:40 CET 2000
On Tue, 12 Dec 2000, Vlad Dumitrescu wrote:
>The problem I stumbled upon is how to handle simulation time. My
>thought was to have processes run free, and a supervisor one (the
>"world") to check on them and collisions and such. But that is a
>completely different paradigm than the one I used before (the
>"objects" are run in the "world" thread, under it's control) and I
>can't make it work.
Thomas Arts and I recently had a discussion on how to perform model
analysis on running product code. We agreed that one problem was that
you cannot "step" the system (using e.g. breakpoints, you can step one
process, but this throws all timing dependencies out of whack.)
Our idea was to run two OS threads in the Erlang VM: one that controls
the internal Erlang clock, and one that runs the Erlang scheduler; the
thread that controls the clock tells the scheduler thread when to
execute the next reduction, and increments the internal notion of
time, so that erlang:now(), the timeout queue, and the calendar
functions operate realistically.
I don't know how hard this would be, but over a cup of coffee, it
didn't seem that hard. (:
>More precisely, the Erlang multitasking strategy gives no control
>over when to yield execution. An Erlang "timeslice" might include
>very different lengths of "simulation time".
A few comments:
- The upcoming Erlang processor will schedule on clock cycles, which
should give very even scheduling
- I'm trying to get a prestudy going on porting Erlang natively to OSE
Delta (http://www.enea.com/) This seems attractive, not only because
OSE Delta is used extensively within Ericsson, but also because OSE
threads have many of the characteristics of an Erlang process.
However, the OSE kernel is fully preemptive, i.e. a thread can be
interrupted even while executing a system call. I don't know if this
is necessarily good or bad, but it seemed to bear on your question.
- There is a BIF called erlang:yield(), which can be called by a
process to yield execution to others. This can be used to compensate
for strange side-effects of the (uneven) reduction-based scheduling.
It is implementation-dependent, and not recommended for use, but...
>A solution I came up with is to have the world doing the
>synchronization by sending "tick" messages to each object. But that
>gives a lot of traffic! And it's not elegant at all.
>Can anyone give me some hints of whether it is possible to
>synchronize everything in a clean way, and if yes, how? Or at least
>some pointers for where to look further.
I know of no clean way to implement another scheduling mechanism on
top of the existing one. You _could_ try to run everything in one
process (I can't believe I'm saying this) if you take great care to
emulate the OTP behaviours. It would be possible, for example to make
a multi-gen_fsm, which keeps process states in, say, the process
dictionary, and calls different callback modules as if they were
normal gen_fsm:s. This puts some restrictions on your FSMs (assuming
you even have some): they can't assume that they "own" the process in
which they execute, for example. Another way is to use something like
dispatcher-1.0, which spawns off temporary gen_servers. This way, each
gen_server or gen_fsm would have its own process, but the pid would
change for each request/event. This might be useful for a simulation,
but I wouldn't recommend it for a product.
Ulf Wiger tfn: +46 8 719 81 95
Senior System Architect mob: +46 70 519 81 95
Strategic Product & System Management ATM Multiservice Networks
Data Backbone & Optical Services Division Ericsson Telecom AB
More information about the erlang-questions