Copernicus: Generating Code from polymorphic components and heterogenous models.
Stephen Neuendorffer and Christopher Brooks|
|Advisor:||Edward A. Lee|
The high-level of abstraction possible in component-based modeling offers
many advantages, such as simulation speed, the strength of formal models of
computation, etc. However, the fundamental weakness of high-level modeling
is the difficulty of actual implementation. Traditionally the easiest way to
get high performance has been to translate the model by hand into a
low-level implementation language. Automatic code generation from the
model is sometimes possible by assembling the component specifications,
but only with serious performance penalties.
These penalties come from several sources:
At some level, these problems can be ameliorated using traditional code
generation strategies. If a component is too flexible to generate good code,
then it can be replaced with a specialized hand-written version. If there is
unnecessary structure in the model, then change the model so that the structure
is removed. However, these solutions conflict directly with good engineering
practice, and greatly complicate the implementation procedure.
- A component in the modeling environment is inevitably built to be
easy to design with. Components can often accept a variety of data types
(type-polymorphism), can be used in a variety of control or communication
models (domain-polymorphism), can be configured with different parameters
(operational-polymorphism), and can be used in any environment
(context-polymorphism). This flexibility directly conflicts with the goals
of most optimized implementations.
- A model consists of components, their ports, and the connections
between those ports. The model of computation associated with a model
determines how connected components communicate and control their execution.
In some cases the boundaries of components correspond to physical boundaries
of the implemented system. For example, there might be one component for
each physical processor that is connected to a system bus. However, the
boundaries of components often have no physical importance in a system. They
are specified arbitrarily by the system designer, or because of the
social structure of group designing the model, or because of the availability
of reusable components. Simple code generation strategies blindly preserve the
structure of the model, which can result in unnecessary overhead.
We are developing a code generation strategy that attempts to handle these
difficulties automatically. The key idea is that we combine code generation
from a model with compilation of the code for individual actors. We call this
strategy Co-compilation. This strategy directly addresses the
difficulties above. We parse the code for an actor and specialize it
its use in a particular model (the types, the particular domain, the values of
parameters and the connections that have been made to it). We can also perform
cross-actor optimizations to eliminate or reorganize the structure of a
Co-compilation also offers a straightforward path to code generation from
heterogenous models that contain different communication and control
strategies organized in a hierarchical structure. We anticipate being
able to generate code for a model at one level of the hierarchy and then
use the generated code as a component at a higher level of the hierarchy.
This can result in reduced overhead as well, since a system designer is not
limited to a single model of computation.
We have implemented this code-generation strategy as the Copernicus package,
which is part of
Copernicus parses the Java bytecode for actors, optimizes it, combines it
with code generation from the model and outputs Java bytecode. The resulting
generated code is currently useful for high-speed compiled code simulation.
We are currently exploring how to generated code for embedded architectures
and for FPGAs.
Last updated 11/01/04