Simulating computer behavior with the CSE

The Cell Simulation Environment can be used to simulate systems from entirely different domains. For example, "reaction sets" can be constructed to provide simulations of computer behavior in several different ways, and this page will discuss a couple of alternative approaches.

A simple example

The first approach is quite straightforward. It represents computer "components" such as CPUs and disk controllers as catalysts that transform the state of units of information flowing in the system. For example, it uses reactions like:
                            CPU
      runnable_request --------------> disk_activity_request
with a probability of 1.0 and some duration, possibly greater than 1, to represent a brief period of program execution generating a disk read or write.

Note that when this reaction executes, the CPU count will be reduced by one for the duration of the executing state and when the CPU count appears in a graph you can tell when the CPU is busy.

title: User preparing to respond.
reactants: prompt
catalysts: user
products: user_request
probabilities: 1.0
duration: 100

# The next two reactions express the fact that the image may already be in memory.
title: Network processes request from user.
reactants:user_request,
catalysts: server_NIC
products: IO_disk_activity_request
probabilities: 1.0
duration: 2

title: Network processes request from user.
reactants:user_request,
catalysts: server_NIC
products: runnable_request
probabilities: 1.0
duration: 2

# The next three reactions express CPU use options.

title: Relinquish a time slice...probability determines average duration of slice.
reactants: runnable_request
catalysts: CPU
products: runnable_request
probabilities: .9
duration: 10

title: Request IO_disk activity...probability determines frequency of disk requests.
reactants: runnable_request
catalysts: CPU
products: IO_disk_activity_request
probabilities: .01
duration: 1

title: Finish processing request by issuing new prompt and giving up CPU.
# This probability determines mean amount of last slice.
reactants: runnable_request
catalysts: CPU
products: ready_to_issue_prompt
probabilities: .09
duration: 10

title: Wait in I/O controller queue.
reactants: IO_disk_activity_request
catalysts: IO_controller
products: disk_activity_request
probabilities: 1.0
duration: 1

title: Start disk activity.
reactants: disk_activity_request
catalysts: disk_controller
products: disk_activity_finished
probabilities: 1.0
duration: 50

title: Complete IO controller activity.
reactants: disk_activity_finished
catalysts: IO_controller
products: runnable_request
probabilities: 1.0
duration: 1

title: Wait in I/O controller queue.
reactants: ready_to_issue_prompt,
catalysts: IO_controller
products: server_NIC_activity_request
probabilities: 1.0
duration: 1

title: Start net transmission activity.
reactants: server_NIC_activity_request
catalysts: server_NIC
products: prompt
probabilities: 1.0
duration: 1
Here is an example "molecules" file that can be used with the "reaction set" above:
user = 1        # there must be exactly 1 user per prompt, so see below....
prompt = 1      # the total number of prompts must be the same as num of users.
server_NIC = 2
IO_controller = 5
CPU = 3
disk_controller = 8
Here is a graph of some of the output variable counts produced using the two files above, and without allowing exponential variation in transition durations:

Molecules Molecule count with respect to time step
CPU
IO_controller
disk_controller
prompt
user

The count of available disk controllers is shown in green in this graph. When a disk controller is busy the count is diminished by one. You an get a feel for how much disk activity is occuring by watching this line with respect to the others.

For example, CPU use is reflected by the red line with a beginning value of 3. Periods of CPU use are represented by a drop in the count of available (free) CPUs. You can see the time slices utilized by active processes as relatively ragged sections of this line. Clearly, this example shows relatively light disk use when compared with CPU use.

Note that this kind of run helps debug the reaction set, and would usually be rerun with different parameters, particulary with more users defined in the input "molecules" file, and with transition durations allowed to vary according to an exponential distribution.

Here are some results from a run with 10 users, but without variation in durations. Note that "prompts" are introduced into the system one-by-one separated by 9 time steps in this example. If transition durations werea allowed to vary, this artifice would not be necessary.

Molecules Molecule count with respect to time step
CPU
IO_controller
disk_controller
prompt
user

An "instrumented" example

The simple approach used above cannot indicate system state or "instrument" the simulation very clearly. In the next model, the state of an object is represented as an object. For example, an available CPU is represented as the object "ready_CPU". When that CPU begins to run a process, one "ready_CPU" disappears and is replaced by one "CPU_running_request".

Also, this model assigns probabilities to achieve distributions of reaction durations. For example, the transition from "ready_CPU" to "CPU_running_request" states happens with a probability of 1.0 so that any available CPU must be used. However, the transition from "CPU_running_request" back to "ready_CPU" state occurs with some smaller probability, so as to represent a time step of variable size used by the request.

title: User preparing to respond.
reactants:thinking_user
products: user_request_to_network,waiting_user
probabilities: .1
duration: 1

title: Network processes request from user.
reactants:user_request_to_network,ready_server_NIC
products: busy_server_NIC
probabilities: .7
duration: 1

title: Network completes request from user.
reactants:busy_server_NIC
products: user_request_ready_for_IO_controller,ready_server_NIC
probabilities: 1.0
duration: 1

title: IO controller processes request.
reactants: user_request_ready_for_IO_controller,ready_IO_controller
products: IO_controller_reading_user_request_from_NIC
probabilities: 1.0
duration: 1

title: IO controller completes request.
reactants: IO_controller_reading_user_request_from_NIC
products: user_request_ready_for_processing,ready_IO_controller
probabilities: 1.0
duration: 1

title: Request that the program image be loaded into memory, if necessary.
reactants: user_request_ready_for_processing,ready_CPU
products: IO_disk_activity_request, ready_CPU
probabilities: 1.0
duration: 1                     # whichever gets tried first runs. 

title: OR, if it is already in memory, just make it runnable.
reactants: user_request_ready_for_processing
products: runnable_request
probabilities:1.0               # whichever gets tried first runs.

title: Take a time slice.
reactants: runnable_request,ready_CPU
products: CPU_running_request
probabilities: 1.0
duration: 1

title: Relinquish a time slice...probability determines average duration of slice.
reactants: CPU_running_request
products: runnable_request,ready_CPU
probabilities: .1
duration: 1

title: Request IO_disk activity...probability determines frequency of disk requests.
reactants: CPU_running_request
products: ready_CPU,IO_disk_activity_request
probabilities: .001
duration: 1

title: Finish processing request by issuing new prompt and giving up CPU.
# This probability determines mean amount of CPU devoted to request.
reactants: CPU_running_request
products: ready_CPU,IO_NIC_activity_request
probabilities: .1
duration: 1

title: Wait in I/O controller queue.
reactants: IO_disk_activity_request,ready_IO_controller
products:IO_controller_busy,disk_activity_request
probabilities: 1.0
duration: 1

title: Start disk activity.
reactants: disk_activity_request,ready_disk_controller,IO_controller_busy
products: disk_controller_busy,ready_IO_controller
probabilities: 1.0
duration: 1

title: Complete disk activity...prob determines duration of disk activity.
reactants: disk_controller_busy
products: disk_activity_finished,ready_disk_controller
probabilities: .01
duration: 1

title: Complete IO controller activity.
reactants: disk_activity_finished,ready_IO_controller
products: IO_disk_activity_finished,IO_controller_busy
probabilities: 1.0
duration: 1

title: Complete IO_disk activity.
reactants: IO_disk_activity_finished,IO_controller_busy
products: runnable_request,ready_IO_controller
probabilities: 1.0
duration: 1

title: Wait in I/O controller queue.
reactants: IO_NIC_activity_request,ready_IO_controller
products: server_NIC_activity_request,IO_controller_busy
probabilities: 1.0
duration: 1

title: Start net transmission activity.
reactants: server_NIC_activity_request,ready_server_NIC,IO_controller_busy
products: server_NIC_busy,ready_IO_controller
probabilities: 1.0
duration: 1

title: Complete net transmission activity...prob determines amount of net time required.
reactants: server_NIC_busy,waiting_user
products: server_NIC_activity_finished,ready_server_NIC,thinking_user
probabilities:.7
duration: 1

title: Complete IO controller-NIC activity.
reactants: server_NIC_activity_finished,ready_IO_controller
products: IO_NIC_activity_finished,IO_controller_busy
probabilities: 1.0
duration: 1

title: Complete IO_NIC activity.
reactants: IO_NIC_activity_finished,IO_controller_busy
products: ready_IO_controller
probabilities: 1.0
duration: 1
Note that time scaling is difficult with this kind of modelling, and choice of probabilities is tricky, but here are some results to demonstrate the usefulness of this approach. This run shows a simulation running with 10 users (still without transition duration variation)..

Molecules Molecule count with respect to time step
CPU_running_request
IO_controller_busy
disk_controller_busy

This system shows relatively intense disk activity compared with CPU activity. Many disk controllers are busy, while CPUs are relatively inactive.

Summary and a comment

This page has shown a couple of ways the CSE can be used to simulate computer systems. Another obvious application would be computer networks, but this must wait for a warmer day.

It is interesting to note that variable counts in these simulations do not show exponential distributions when examined using Detrended Fluctuation Analysis. The number of available disk controllers, for example, showed distributions similar to power-law (DFA slope of .95), with fixed durations, and runnable_requests showed a distribution somewhere between power-law and random walk (DFA slope of 1.29), when transition durations were exponentially distributed. To the naked eye, runnable_requests showed a distribution not unlike log-normal.

Michael Grobe
December 2003