SimulationPerformance

<em>Can't find PageSubscribe to include!</em></em>

Performance Issues with SystemC

Designers in general want to achieve high simulation performance, especially with SystemC. It is always said that SystemC is a highly performant simulator, but the point is, that simulation performance is not always the task of the simulator, more it is a task of modeling.

Several modeling techniques exist, and for sure, each of it has its own challanges, advantages, and drawbacks. Suppose, for example, modeling at the RT level, and compare it to simulators like VHDL or Verilog. More often than not, the simulation speed may be comparable. One time SystemC may be faster, another time it may be vice versa. So what is the point when talking about simulation performance ?

Style of Modeling

The point is the style of modeling -- that's when modeling at higher levels of abstraction comes in. Suppose modeling at the Transaction Level. Here SystemC will surely be more performant than others, and that's because of the style of modeling.

Through abstraction you, as a designer, can hide unnecessary specifications in an early stage of the work flow. By doing this, SystemC will simulate at a higher speed, and that's due to a different and new methodology (TLM). When omitting low-level details, the simulator (i.e. the SystemC kernel) will not have to keep track of thousands of event queues, hundreds of signals, and much more data to move from one point to another.

There should ideally be only a few numbers of channels which enable all communication that must be done. For example, see the simple_bus example of SystemC, where the bus is modeled as a single hierarchical channel. That way it becomes possible to model an entire system, and still with a very high simulation performance.

Mixing Modeling-Techniques

If you nevertheless have to use modules specified and implemented on RT level, but actually want to use a methodology like TLM, you can use adapters. Adapters are special modules with two interfaces, wheras one side will accept the low-level RTL signals and the other side will issue transactions by transforming those signals into a representation, which simulates faster. On the other side, the adapter module has to react on incoming transactions and then handle the singal handshaking to the low-level interface.

Events and Time

Another key point is, to not use clocks when not necessary, e.g. use an untimed model if you just want to evaluate a new algorithm and timing is not needed. Sometimes it may be more efficient to simply delay single modules, instead of using a clock, and check the rising edge each cycle.

Consider waiting on one particular signal (with the command wait), instead of executing each and every process when it's not needed directly. That just produces more arising events, and thus more time consumption in terms of simulation performance. A simple sequential execution would suffice in special cases, hence your model will simulate a lot faster.

If you want to use a clock, though, maybe think about the clocks' resolution. It may not be necessary to define a period of, say, 2.75 milliseconds, if you don't really need to run your system at the predefined speed. The simulation kernel always wants to keep track of time. Simply using a clock with the default period of SystemC should simulate faster.

Also consider not using multiple clocks in your design if it's not needed directly.

Data Types

Another important point covers the usage of data types. As we know, SystemC offers a lot of specialized data types for serveral purposes (read more). But sometimes the types in use are not needed, in the manner the functionality they provide. Functionality is fine, but always goes hand-in-hand with overhead if used.

The point is, that native C++ data types are perfectly satisfactory for most tasks, especially at higher levels of abstraction. It is also good to know, that native C++ data types can be used with all template classes of SystemC without any problems. So, it is sensitive to use simple 32-bit integers (C++) and not sc_int, if only the value of the integer is interesting.

Even if you wand to access single bits of an integer, use bit-masks and shift-operations to access the data wanted. There may be no need to use the type sc_int with its range() member-function. All those considerations imply the same idea: the level of abstraction, the design in early phases and the overall performance of the simulation.

When heading for synthesis, the usage of SystemC data types makes more sense.

Large Structures and Pointers

SystemC allows the designer to define its own data types, to wrap certain parameters together (e.g. the use of structs for one video frame). This may look attractive at a first glance, but bears some hidden burdens if not used correctly.

Think of using such structures, which roam from one module to another over a bus-system. Easy to maintain, it may be, but you should always think of the memory usage if entire objects (talking from programmers view) need to be copied. Not to digress, it will always consume time, if objects are duplicated and then deleted if no more needed.

When using such structs, consider the use of pointers (in the sense of the C++ programming language). That way, single objects only exist once -- all you then have to copy is the memory-address of the object, which if far less memory since it it only an address and the object only exists once.

If such objects tend to be used from several places, think of using smart pointers. Smart pointers offer the ability to use the object from several places in your code, without copying entire objects, rather using a simple counter to know from where this object is being used. Also, smart pointers facilitate prevention against memory leaks and memory corruption, which are errors not easy to find, and frustrating to search.

Compiler Optimizations

Another key point, which is often outside the designers mind, is the compilation of the design. If you use an IDE for your SystemC design, there are probably debugging-options enabled by default.

As in software-design, compilated code with enabled debugging information will always run a lot slower, because debugging information swells the binary code, thus resulting in overhead at run-time. Most compilers offer the ability to compile with code-optimizations, e.g. using inline expansion, elimination of dead code, constant propagation, loop transformation, and even more...

So, you should check your compiler options before making extensive simulation runs, apart from debugging. The GNU compiler, for example, uses the flag -g to enable debugging, or -O2 and -O3 to enable optimized and even more optimized code, respectively.

Also, it may be sensitive (but not mandatory) to install multiple versions of SystemC: one with debugging options enabled, and another without debugging options, thus using optimizations.


PageComment2(commentfirst=1,nosmiley=1,articleview=1)


NewPage(PublicTemplate,New Page Here,SystemC/SimulationPerformance)