Simulating Resources Using the Maude Backend

Introduction

This section describes language features related to deployment components. Most of these features are implemented on the Maude backend and ignored on the Java backend.

ABS models can be augmented with resource information and the effects of resources during execution can be simulated on the Maude backend. Resources are contained in deployment components, which provide a context in which concurrent object groups and their objects execute. Deployment components can be used to model servers, virtual machines, nodes in a network, and basically any entity that constrains execution of code running in its context.

At the moment we only model CPU capacity. A deployment component (DC) can contain a certain "CPU capacity", which provides an abstract model of speed relative to other DCs. I.e., a cpu capacity of 50 is "twice as fast" as 25.

Executing statements costs a certain number of resources, which are refilled in each time interval -- since CPU speed is related to performance and hence time, simulations involving performance characteristics must be done using the timed interpreter.

Language Elements

All identifiers described in the following are contained in the module ABS.DC.

Resource Types

Deployment components carry a specific capacity, which is a possibly infinite number of CPU "cycles". The partial function capacity returns the number of resources, if finite.

data DCData = InfCPU | CPU(Int capacity);

Deployment Components

A deployment component ("DC") is modeled by an ABS class and interface DeploymentComponent which is contained in the standard library in the module ABS.DC. DCs are initialized with resource data which is used by the Maude backend to simulate cpu usage and performance behavior of models.

interface DeploymentComponent {
    DCData available();
    Int load(Int periods);
    DCData total();
    Unit transfer(DeploymentComponent target, Int amount);
    Unit decrementResources(Int amount);
    Unit incrementResources(Int amount);
}

class DeploymentComponent (String description, DCData cpu)
implements DeploymentComponent {
    ...
}
  • The call available() returns the number of currently available resources. (The value will change during execution, hence code using this method should be aware of the obvious race condition.)
  • The call load(n) returns the average load for the last n time periods as an integer between 0 and 100.
  • The method total() returns the number of resources currently available per time unit.
  • The method transfer(target, amount) transfers a number of resources from the current DC to target. If either the current or the target DC have an infinite number of resources, their respective values are not changed.
  • The methods decrementResources and incrementResources are used to implement transfer, but can also used on their own to increment or decrement the amount of resources of the current deployment component.

Using Deployment Components

An optional annotation [DC: x] attached to a new cog statement expresses that the new object's cog will run in the context of deployment component x. By default, a new cog runs in the same context as the process that generates it. The main block runs in a DC with no resource limits.

interface Server { ... }

class ServerImp implements Server { ... }

{
  DeploymentComponent machine = new DeploymentComponent("remote",
      CPU(20));
  [DC: machine] Server x = new cog ServerImp();  // running in dc `machine'
  Server y = new cog ServerImp();                // running in current DC
}

Accessing the Current Deployment Component

def DeploymentComponent thisDC() = builtin;

The thisDC() "function" returns the current deployment component, i.e., the one that was given as annotation at the new cog object instantiation. thisDC returns null if no deployment component was specified. (Due to implementation issues, models containing thisDC() cannot be currently compiled on the Java platform.)

Expressing statement costs

The annotation [Cost: x] s expresses that executing the statement s will consume x CPU resources. If the current DC does not contain enough resources, the process will block until the next time unit.

Default statement costs

By default, statement execution costs nothing (i.e., the machine is infinitely fast), which preserves the normal semantics of timed ABS where only explicit duration or await duration statements advance the clock. By compiling ABS models with the command-line parameter -defaultcost=n, all statements without an explicit [Cost: x] annotation will take n resources to execute. This approximates "normal" CPU behavior a bit more closely, but still disregards the cost of evaluating expressions (assignment of a complex expression will take more time on a real machine than assignment of a constant).

Changing the deployment component

A statement movecogto dc; transfers the current cog and all its objects to the deployment component dc. On backends without resource modeling features (Java, Scala) this translates to a skip.

Future Work

  • The thisDC function is currently undefined in the Java backend and will lead to a compile-time error.