Figure 14. Breaking up larger loops into smaller loops may enable each loop to be pipelined more efficiently.
Software pipelining does not happen with careful analysis and structuring of the code. For example, loops that do not have enough processing will not be pipelined. On the other hand, loops that have too much processing will not be pipelined because the loop body will exhaust the available registers! Also, function calls within a loop will not be pipelined. Instead, if you want a pipelined loop, replace the function call with an inline expansion of the function.
One of the drawbacks of pipelining is the disabling of interrupts. An interrupt in the middle of a fully primed pipe destroys the synergy in instruction execution. The compiler will protect a software pipelining operation by disabling interrupts before entering the pipelined section and enabling interrupts on the way out (Figure 15). This means that the price you pay for the efficiency in software pipelining is paid for in a non-preemptible section of code. The programmer must be able to determine the impact of sections of non-preemptible code on real time performance.
Figure 15. Interrupts are disabled during a software pipelined section of code
Embedded CPU Power Consumption
Given the proliferation of portable embedded devices, power consumption has become almost as important as execution time and memory use, and in some cases, the most important parameter to optimize in an embedded system. Most modern CPUs are designed with power consumption in mind to some degree. Many embedded processors now include features such as run-time power modes that are used to scale power consumption. One of these modes is referred to as the "idle mode". In idle mode the instruction-executing portion of the processor effectively powers down. Other parts of the processor including the peripherals and interrupt logic remain powered on. While the processor is waiting for something to happen as opposed to the processor actively executing instructions [1].
Speaking of power, it is important to distinguish between power and energy. Roughly speaking, heat depends on power consumption, while battery life depends on energy consumption. Power is energy consumption per unit of time. In processor design, power consumption is proportional to the square of the supply voltage, so the lower the supply voltage the better from a power perspective. More toggling means more activity which means more power. The goal of low power design and programming is to minimize this activity whenever possible. Another form of power consumption, leakage, deals with basic circuit characteristics, and can be eliminated by disconnecting power [2].
There are several CPU power saving strategies available to the embedded system designer. These include [2]:
- Reducing the power supply voltage.
- Running at a lower clock frequency.
- Disabling functional units with control signals when not in use.
- Disconnect parts from power supply when not in use.
There are two main power management styles used by embedded programmers:
- Static power management: this approach does not depend on CPU activity. An example of this style is user-activated power-down modes.
- Dynamic power management: this approach is based on CPU activity. An example of this approach is disabling functional units
The embedded designer must keep in mind that there are also power down costs. Power down costs include factors such as the time to enter and exit the mode and the energy consumed by doing this. The designer must determine if going into a power-down mode is worthwhile. One way to make this determination is to model the CPU power states with power state machine.