Multi-core processors offer significantly greater processing capacity per watt, per ounce, and per square inch than conventional uniprocessors. In this class, participants learn how their existing software can realize this performance advantage with a minimum of recoding. The class begins by reviewing the advantages of various multiprocessing models (e.g. AMP, SMP, BMP) and discusses how each model affects code migration, parallelism, debugging, shared-resource management, and scalability beyond two cores. It then reviews strategies for distributing software applications and services across multiple CPU cores. The class ends with a discussion of how system-tracing tools can achieve maximum utilization of every core in a multi-core processor.
Getting your software up and running on a multi-core processor is, in many cases, fairly easy. The real challenge is getting the software to make full use of all the processor’s cores. This class provides examples of multi-core optimization techniques and discusses how developers can use visualization tools to characterize multi-core behavior and measure performance improvements. The class explores how developers can use threading models to create multiple concurrent tasks and parallel processing; it also discusses how to minimize lock contention by using mutexes to engineer the optimal level of lock granularity.
When it comes to power management, no two mobile devices are the same. Every device presents a unique set of power management requirements, such as controlling the power modes of custom hardware, delivering predictable response times while in low-power states, and fine-tuning power consumption in response to application-specific events. This class explores how to identify system characteristics that must be addressed by power management, select an appropriate power management architecture, and design a power policy that achieves the lowest possible power consumption while satisfying your device’s performance constraints. Special attention will be paid to approaches that move control of power consumption out of the OS (where it traditionally resides) and into the hands of the system designer. Through such approaches, developers can create power policies that address events invisible to the OS, achieve finer-grained control over the power consumption of each peripheral, and address a wider range of operational scenarios.
The massive amount of software in today’s telematics and infotainment systems can cause significant delays at integration time, when unexpected interactions between software components result in anything from a slow user interface to complete system failure. Using a handsfree phone system as an example, this class explores how time partitioning can prevent these problems, resulting in faster integration, better CPU utilization, and highly predictable performance. Briefly stated, time partitioning allows the system designer to allocate a guaranteed portion of CPU time to every software subsystem, thereby preventing any subsystem from monopolizing CPU cycles needed by other subsystems. The class also discusses other techniques for solving integration problems, such as priority reassignment and code optimization, and compares their benefits to those of partitioning.
An “always on” human machine interface (HMI) is a key requirement for many industrial control systems. Nonetheless, the HMI can become unresponsive or unusable when system events impose a heavy load on the CPU. This class explores how system designers and developers can use CPU time partitioning to prevent this problem and guarantee both local and remote operator access in any scenario. With time partitioning, developers and system designers can allocate a guaranteed minimum percentage of CPU time to each software subsystem, regardless of system load. As a result, each subsystem, including the HMI, can remain continuously available.
This class explores how resource partitioning can improve the security, availability, and dynamic upgradeability of embedded systems. Using this technique, developers can place programs into virtual compartments, called partitions, and allocate a guaranteed amount of memory and/or CPU time to each partition. These resource guarantees can safeguard the system against denial-of-service (DoS) attacks; prevent poorly written or malicious tasks from monopolizing resources needed by other tasks; ensure that lower-priority functions always have the CPU cycles they require; and allow the system to dynamically support new services while ensuring that existing services still have sufficient computing resources.
Software bugs that make it to market not only cause product instability and loss of system availability, but also result in unhappy (and fewer) customers. Unfortunately, conventional debugging methods can themselves interfere with the availability, performance, and correct behavior of the affected system. Thus, this class examines debug and information-gathering techniques that can maintain system availability while generating artifacts that help diagnose and resolve software failure. The class will include a demonstration of in-field debugging techniques.
Embedded systems today use flash memory in ways that no one thought possible a few years ago. In many cases, systems need flash chips that can survive years of constant use, even when handling massive numbers of file reads and writes. As a further complication, many embedded systems must operate in hostile environments where power fluctuations or failures can corrupt a conventional flash file system.
This class explores the current state of flash file system technology and discusses criteria for choosing the most appropriate file system for your embedded design. For example, should your design use a FAT file system or a transaction-based file system, such as JFFS or ETFS? Also, what file system capabilities does your design need the most? Does it need to run reliably on low-cost NAND flash or recover quickly from file errors? Does it need to perform many reads and writes over an extend period of time? This class addresses these issues and examines the importance of dynamic wear leveling, static wear leveling, read-degradation monitoring, write buffering, background defragmentation, and various other techniques.