By BDTI, 6/15/2005
Alan Kamas contributed to this article.
As processors have steadily become faster and less expensive, systems with signal processing algorithms have increasingly been implemented as software running on a processor. One of the first steps in the software development process is choosing the development language. Not too long ago, the choice of language was simple: only assembly language was efficient enough to meet the demands of most signal processing applications. Now that processors are faster, memories are larger, and compilers are better, there are higher level language choices. This article looks at the advantages and trade-offs of languages for signal processing software development—starting at the bottom and moving up from there.
Assembly Code: Next to the Machine
Hand optimized assembly code is still the most reliable way to get the maximum performance from a processor. This is an important consideration because demanding signal processing algorithms can tax even the fastest processors. The efficiency provided by assembly code might also be required for systems that use a slower processor to meet tight cost or power budgets. In order to realize the potential performance advantages of programming in assembly, the programmer must have an intimate knowledge of the internals of the processor. For example, the programmer must understand the details of the registers, specialized instructions, pipeline stages, memory accesses, and interrupts. Learning these details can be a slow, painful process. In addition to the long learning curve, it takes more time to code and debug in assembly. Because of these difficulties, a design may be prototyped or simulated in a higher level language first before it is rewritten in assembly for implementation on the embedded processor.
Another challenge with assembly is that it can be very difficult to read someone else’s code—or even to read one’s own code. This makes assembly code more difficult to maintain, modify, and upgrade. In a world of multiple and “evolving” standards, code updates can be a serious issue. Finally, the fact that assembly language is so close to the machine generally makes the code non-portable. If a different processor is chosen later, then the code will likely have to be rewritten. Figure 1 illustrates how assembly language can vary dramatically from one processor to the next.

Due to these serious drawbacks, assembly language is typically only used when necessary. The most critical functions may be coded in assembly while the rest of the system is written in a higher level language such as C. Recognizing this, some chip vendors and software vendors provide libraries of common functions written in hand coded assembly language that may be called from within the user’s C code for better performance. For more on function libraries, see “Software Building Blocks for Signal Processing Applications”.
C: The Common Choice
Compiled code may not run as efficiently as expertly crafted assembly code, but compiled C code is often efficient enough. Some general-purpose processors have had good compilers available for many years, and the compilers for many DSPs have improved in the last few years. Similarly, general-purpose processors have long been designed to be good compiler targets, and DSPs have recently evolved to better support high level languages and to make the compiler’s job easier. For more on compilers, see “Tools Make the Difference”. Often, code efficiency is not the most important factor when choosing a language. Since it is easier to program in a higher level language, development can be much faster than with assembly. But the real gain is in the debugging and maintenance effort. Errors found by a compiler may be easily fixed on the spot. Similar errors in assembly code may not be found until the code is run and debugging begins. Maintenance is easier too, which leads to faster turnaround times for fixes and upgrades. But these advantages are offered by all high-level languages. Why choose C?
|