Simulation Performance Driven By Model Efficiency

Well-written and efficient models equal high performance simulation platforms but the challenge is understanding what it takes to create one.

popularity

In real estate it’s all about location, location, location. For system level simulation it’s all about performance, performance, performance. I have heard many opinions on the performance of SystemC and TLM simulations: some positive, some negative, much of the opinion based on hearsay or other unreliable information. I believe the performance of the simulation is mainly driven by the model efficiency. Well-written efficient models provide high performance simulation platforms. The challenge is to understand what it takes to create a well-written model.

Recently I took some time to go back over some user code examples that were specifically identified as having performance issues. In going through this code I saw three general issues that caused most of the performance issues in the code base, and from this perspective it’s easier to identify what makes a poor model.

The first issue was related to doing something periodically, this showed up in a number of different forms the simplest example being a timer.  A typical low performance implementation of a timer would be the following:

<setup count and time_period>
for (int i=0;i<count;i++) wait(time_period);
<trigger activity>

This is a common construct in RTL for creating a timer, but it is very inefficient in an abstract model.  For an abstract TLM a more efficient implementation would be the following:

<setup count and time_period>
wait(count * time_period);
<trigger activity>

Making this change in one user platform example improved the simulation performance of the platform by multiple orders of magnitude.

The second issue was related to communication of information through a low level signal.  An example would be communicating a frequency value from one model to another by toggling a signal at a specific frequency.  The receiving model must monitor the signal and calculate the frequency based on the time elapsed between toggles.  Rather than using this approach the driving model could send the frequency value directly as an abstract value and only resend the frequency when it is changed.  Again this kind of a change in modeling can lead to orders of magnitude improvement in simulation performance.

The third issue I saw was related to polling of values.  In an RTL implementation a waiting model may poll a controlling model’s registers looking for a specific change in value before progressing.  While this may be the low level implementation, the abstract model can be written such that the controlling model sends a message to the waiting model when the value change occurs.  In this way we can avoid all of the events associated with checking the value when it has not changed.  Like the other examples this can provide multiple orders of magnitude improvement in the simulation performance.

All three of these issues involve moving from a low level/RTL approach in modeling to a more abstract transaction level approach.  For the examples I reviewed these modeling approaches caused the vast majority of the performance problems in the platforms that were identified as having poor performance.   After addressing these issues each platform’s performance improved by orders of magnitude.

One “Red Herring” issue that I have heard from numerous sources is the recommendation that users should write their SystemC models using sc_methods and avoid sc_threads.  I created a simple producer/consumer example using sc_methods in one implementation and sc_threads in the other implementation.  Comparing the simulation performance of the two implementations I saw a performance improvement of 25% in going from sc_threads to sc_methods.  A complicating issue in using sc_methods is the level of modeling they encourage.  In the user examples I reviewed many of the models written using sc_methods were also the models that were written at a lower level of abstraction with poorer simulation performance.

My conclusion from all of this is that while sc_methods are somewhat faster than the sc_threads, the difference is not significant.  The dominant issue in simulation performance is the level of abstraction of the models.  Abstract models, which eliminate unneeded simulation activity, have a tremendous effect on the performance of the simulations.  With appropriately abstract models I am seeing virtual platforms delivering simulation performance equivalent to systems running at hundreds of megahertz.