 an Arm A72 core. Compare this to the theoretical expectation set earlier ("...x3 real operations " per LLR) without any overheads and the later assumption of 50% overhead for low-level kernel implementation. It is to be noted that 6 CPU clocks in an Arm A72 with 128-bit vector support gives 6X8X2 = 96 operations for generation of 16 LLRs or 3 operations per LLR. This great match between theory and practice may be rare but the point is the same nonetheless: over time, we learn how to map theoretical calculations to practical implementations well. Phase 3: stack development The last stage in the analysis cycle is actual software implementation where we compare sub- system (transmit chain, receive chain, etc.) level performance against the initial theoretical projections to find out where performance bottlenecks in the software implementations exist and optimization is needed. Chapter 9 Software performance 319 Central Processing Unit loading summary Although the per-component cycle counting provides good insight into which components need to be optimized, it is not always the best tool to identify where the cycles are con- sumed. For this purpose, a CPU loading profile, at a very fine granularity (i.e., per symbol name) is more useful. An advantage of using Linux as a development environment is that such profile can be generated with open-source tools such as Oprofile (http://oprofile.sour- ceforge.net/about/). Oprofile is a system-wide profile for Linux systems that helps identify high-level hotspots and areas to delve deeper into for optimization. Oprofile tools are com- monly used and included popular commercial Linux distributions including Red Hat Enterprise Linux and SUSE. System-on-Chip performance counters Both software cycle counting and Oprofile do not provide insight into the SoC-level perfor- mance metrics that we established before, such as: Target Instructions Per Cycle/Clock (IPC) Including associated L1/L2 ICache and DCache hit/miss ratios. Gives insight into level of optimization of the software a