CC++ [18] is an object-parallel language that bears some similarities to Structured Dagger. CC++ is a thread-based system. A computation consists of one or more processor objects each with its own address space. Objects within these processor objects can be accessed by remote objects using global pointers. Within individual processor objects, new threads can be spawned using the structured constructs par, and parfor, and the unstructured construct spawn, which creates a new parallel thread. Multiple threads created by these statements may be executed by different processors, or interleaved on the same processor, and they may share variables.
The par and parfor constructs of CC++ are analogous to the overlap, and forall constructs in Structured Dagger. However, they are different in a fundamental sense: two statements in a par construct may actually be executed in parallel by two different processors, whereas two constructs in an overlap statement are always executed by the same processor. Also they can interleave only in a disciplined fashion: only entire when-blocks can be interleaved, based on the arrival of messages, and not the individual C++ statements.
The most important difference between Structured Dagger and CC++ (and other systems such as Chant [29]) has to do with threads. Using threads creates a flexibility, but at a cost: thread context switches are more expensive than message-driven invocations of methods in Charm++ or Structured Dagger. Also, threads waste memory: creating hundreds or thousands of threads, each with its own stack, may not be possible, whereas a large number of parallel objects can easily be created without reaching memory limits.
ABC++ [4] is a thread-based object-parallel language. Both synchronous and asynchronous remote method invocations are allowed. There is a single thread associated with each parallel object. This thread receives messages corresponding to method invocations and decides when and whether to invoke methods. Primitives are provided to selectively enable execution of individual methods. Unlike Structured Dagger, no direct expression of control flow across method invocations is possible.
The enable set construct [20] addresses the issue of synchronization within Actors [1]. Using this, one may specify which messages may be processed in the new state. Any other messages that are received by an actor are buffered until the current enable set includes them. The ordering constructs in Structured Dagger achieve this in a cleaner manner. Also, there is no analogue of a when-block, viz. a computation block, that can be executed only when a specific group of messages have arrived.
While Structured Dagger presents significant performance advantages because it does not use threads while simplifying expression of control flow within a component, for some cases, such as when converting legacy codes to run on top of the message-driven Converse system, it is sometimes easier to use threads. Threaded Simple Messaging (tSM), Threaded message-passing objects (TeMPO), and Parallel Array of Threads (PATH) languages implemented on top of Converse allow one to construct interoperable threaded components. However, for converting legacy codes such as those written in MPI, a better solution is possible as a migration path that uses Converse's user level threads, and the MPI syntax for message-passing. We describe Adaptive MPI, our threaded implementation of MPI on top of Converse in the next chapter.