The execution model of CHARM++ is message-driven [4] wherein Converse treats the parallel machine as a collection of nodes that communicate primarily via messages. Each node is comprised of a number of processors that share memory. When a message arrives at a processor it triggers the execution of a handler function as specified by the message[14]. The message is a contiguous sequence of bytes and has two parts - the header and the data. The header contains a handler number which specifies which handler function is to be executed when the message arrives. Converse maintains a table mapping handler numbers to function pointers. Each processor has its own copy of the mapping.
Communication primitives send messages to the scheduler queues of remote processors, where the scheduler thread finds them and processes them. The Converse scheduler serves not only as a message receiver but also as a central allocator of CPU time. Both locally generated as well as messages from the network contend for scheduling time in the same way.
The parallel programming model of CHARM++ is based on the concept of processor virtualization [6], where the programmer divides the work into a large number of pieces called virtual processors or parallel objects, and lets the runtime system map these pieces to processors. Communication between pieces is based on virtual addresses managed by the runtime system [10], so the system can migrate pieces of the computation between processors without changing the way the pieces communicate, and hence without changing the programmer's view of the computation. The number of pieces a computation is broken into is typically independent of, and normally much larger than, the number of processors. The pieces of the computation are implemented by the programmer as parallel objects, which in CHARM++ are regular C++ objects. As regular C++ objects, CHARM++ parallel objects can contain public and private data and methods as usual.
A machine-generated ``proxy'' C++ object is used to invoke methods on these parallel objects from other processors. As with Smalltalk, we use the term ``send an object a message'' to refer to remote object method invocation via this proxy object. In accord with the message-driven execution model of CHARM++ all computations are initiated in response to messages being received. Method calls in CHARM++ are non-blocking--they are asynchronous method invocations [13], so the caller does not wait for the method to be executed or return a value. Because these remote methods can be called from ``outside'', they are called entry methods or entry points.
In CHARM++ parallel objects are normally stored in an Array [10]. An Array is a collection of parallel objects keyed by an ``array index''. The size of the array is not fixed, and not constrained in any way by the features of the underlying parallel machine such as the number of processors or nodes. Each array element of an array has a globally unique index, and messages are addressed to that index. Most of the data in CHARM++ programs is stored in array elements.
1]
To enable the required tracing for record and replay, a CHARM++ program is linked with the option ``-tracemode recordreplay'' and run with the ``+record'' option, which records message orders in a file for each processor. The same execution order can be replayed using the ``+replay'' runtime option; which can be used at the same time as the other debugging tools in CHARM++.
January 23, 2004
Charm Homepage