Energy & Power · Study deck

Software Optimization Techniques

Picture a battery sensor that wakes every second to ask whether anything happened.

Battery Bruno is your guide for this deck.

optimizationsoftware
Battery Bruno, the module guide, in a scene from this chapter.
iotclass.org

After studying this chapter

Learning objectives

You will be able to:

  • Choose compiler and linker settings from evidence instead of habit.
  • Identify when code size, memory traffic, active time, or wakeups dominate firmware cost.
  • Apply data-layout and buffering changes that reduce copies and memory stalls.
  • Decide when code-level changes such as inlining, lookup tables, or loop restructuring are worth the risk.
iotclass.org

Major section

Start With Firmware That Wakes Too Often · In 60 Seconds

Most wake-ups do no useful work, yet each one starts clocks and code.

  • Firmware means the software stored on the device.
  • Duty cycle means the share of time a device spends active instead of asleep.
  • This runway does not prove that every software change saves energy.

Key terms

Software optimization
Software optimization is the measured process of changing firmware so it does less work, moves less data, sleeps sooner, or fits smaller memory.

Why it matters

A useful change should reduce work without losing required events.

iotclass.org

Major section

Firmware Optimization Loop

It follows one polling example through profiling, one change, a same-workload check, and a written keep-or-rollback decision.

  • The final card therefore asks for the full-cycle trace, correct results, and memory and build-size checks before keeping the change.
  • Bruno sets a battery target, measures wake, work, radio, and sleep, then spots the tall energy bar.
Firmware optimization loop showing profile, choose bottleneck, change one thing, test correctness, measure whole cycle, and record result.
Firmware optimization loop showing profile, choose bottleneck, change one thing, test correctness, measure whole cycle, and record result.
iotclass.org

Major section

Code-Level Changes · Compiler And Build Choices

Compiler flags are a starting point, not an optimization strategy by themselves.

  • You need readable stepping, assertions, and source-level diagnosis.
  • The product needs stable speed without aggressive code growth.
  • Flash, update size, or instruction fetch is the limit.
  • A measured hot path blocks a deadline or keeps the device awake.
Software optimization levers map showing compiler settings, data layout, memory movement, event-driven sleep, and code-level changes.
Software optimization levers map showing compiler settings, data layout, memory movement, event-driven sleep, and code-level changes.
iotclass.org

Major section

Data, Memory, And Copies · Event-Driven Sleep

Data movement can dominate firmware cost.

  • A clean algorithm can still waste energy if it copies buffers, parses verbose payloads, or wakes the CPU for every small transfer.
  • Busy waiting is one of the easiest ways to waste energy.
  • Replacing a polling loop is only useful if firmware has a complete route back to sleep.

Key terms

Verbose logging
Verbose logging is moved outside the critical active window.

Why it matters

Batch when latency allows: Batching can reduce wakeups and protocol overhead, but it must not hide important events or overload buffers.

Sleep-aware firmware timeline showing busy wait replaced by event setup, sleep, interrupt wake, short processing, and return to sleep.
Sleep-aware firmware timeline showing busy wait replaced by event setup, sleep, interrupt wake, short processing, and return to sleep.
iotclass.org

Major section

Polling Keeps The Core Awake; Events Let It Sleep

The processor saves state, runs a deliberately short handler, restores state, and resumes at the interrupted point.

  • That order separates detection from expensive application work: the peripheral can wake the core, but the handler should capture the event and defer longer processing.

Why it matters

The return path matters as much as entry because an interrupt design saves energy only if firmware clears the source, avoids a busy loop, and allows the processor to sleep again after the event is handled.

An interrupt saves CPU state, runs a short ISR, and restores state so the main program resumes exactly where it paused, keeping the core asleep until an event fires.
An interrupt saves CPU state, runs a short ISR, and restores state so the main program resumes exactly where it paused, keeping the core asleep until an event fires.
iotclass.org

Major section

Phoebe's Field Notes: Why "More Than 8000 Days" Is A Ceiling, Not A Forecast · A Busy-Waiting delay() Does Not Sleep, And You Must Offload The Watching

The mathematical gist: A 2,000 mAh, 3.7 V pack stores 7.40 Wh at nameplate conditions.

  • At 2% monthly self-discharge, 29.8% remains after five years and 8.85% after ten, so an ideal 8,000-day current-draw ceiling is not a field-life promise.
iotclass.org

Major section

Compiler Optimization Modes

Optimization flags express a preference to a particular toolchain; they do not guarantee a fixed list of transformations.

  • In common GCC- and Clang-style workflows, a speed-focused -O3 build may inline more aggressively, unroll or vectorize loops, reorder instructions, and create separate fast paths for alignment or aliasing cases.
  • A size-focused -Os build usually discourages growth, favors shorter encodings, and may keep branches or calls that a speed build removes.
  • A size build can reduce fetch energy, yet keep the core awake longer.
  • The winning flag is the one that lowers measured charge per useful task while preserving timing, stack, numerical, and update-slot requirements.
iotclass.org

Major section

Code Density and Instruction-Level Parallelism

Code occupies silicon and consumes energy every time it is fetched.

  • A memory large enough to hold software can dwarf a small processor core, so instruction density can affect area, fetch bandwidth, leakage, and update time.
  • Compressed instruction sets commonly provide short 16-bit encodings alongside wider 32-bit encodings.

Key terms

None
None is a reliable proxy for the other two.
Three instruction-set branches compare compressed 16-bit encodings, CISC complexity, and VLIW parallel bundles under an update-size limit.
Three instruction-set branches compare compressed 16-bit encodings, CISC complexity, and VLIW parallel bundles under an update-size limit.
iotclass.org

Major section

Code Density and Instruction-Level Parallelism (continued)

VLIW therefore exchanges dynamic scheduling hardware for compiler scheduling and can waste code space when parallelism is sparse.

  • Short forms save bytes but have fewer encoding bits, so they may expose only a subset of registers, smaller immediate ranges, fewer addressing modes, or an explicit mode/history constraint on older designs.
  • The assembler expands to a wider form when operands do not fit.
  • None is a reliable proxy for the other two.
iotclass.org

Major section

Vectorization and Tail Handling

The: TAIL [8 9] then branches to masked lanes or scalar cleanup, so the speedup boundary includes setup and remainder work and never reads beyond x[9] merely to fill a vector.

  • The vector loop executes qqq times over qWqWqW elements; a tail path handles the remaining rrr elements.

Key terms

Vectorization
Vectorization is complete only when the remainder path is as deliberate as the fast path.

Why it matters

That removes a scalar loop but does not remove the boundary obligation: the mask must prevent out-of-range memory access and preserve inactive lanes.

Ten scalar array elements become two four-lane vector operations plus a two-element cleanup tail.
Ten scalar array elements become two four-lane vector operations plus a two-element cleanup tail.
iotclass.org

Major section

Vectorization and Tail Handling (continued)

For N=18N=18N=18 and W=4W=4W=4, there are four vector iterations covering 16 elements and two scalar tail iterations.

  • Omitting the tail silently leaves c[16] and c[17] wrong.
  • Some instruction sets provide masked loads and stores, allowing one final vector operation with only the first rrr lanes enabled.
  • so short arrays, tails, alignment repair, alias checks, and memory bandwidth reduce the gain.
iotclass.org

Major section

Predication and Function Inlining · Summary

The lower comparison changes currency from cycles to bytes.

  • A shared call keeps one 12 B body plus call and return boundaries; inlining it at three sites removes those boundaries but copies the body, adding 24 B relative to one copy.
  • If its direction is hard to predict, a misprediction flushes useful pipeline work.

Key terms

Predication
Predication is attractive when executing or issuing the guarded instructions costs less than that penalty and has no unsafe side effects.
If a three-instruction helper
If a three-instruction helper is called in a hot inner loop, this can be valuable.
Branch and predicated instruction timelines are compared beside shared-call and three-site inline code layouts.
Branch and predicated instruction timelines are compared beside shared-call and three-site inline code layouts.
iotclass.org

Deck summary

Key takeaways

Most wake-ups do no useful work, yet each one starts clocks and code.

  • It follows one polling example through profiling, one change, a same-workload check, and a written keep-or-rollback decision.
  • Compiler flags are a starting point, not an optimization strategy by themselves.
  • Data movement can dominate firmware cost.
  • The processor saves state, runs a deliberately short handler, restores state, and resumes at the interrupted point.
iotclass.org

Retrieval practice

Recall check 1 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q1A developer wants to inline a large function that rarely runs. What should the review require?

ASkip correctness checks if the faster loop improves a single benchmark.
BInline the call for savings because reduced call overhead lowers firmware energy and image size.
CIgnore firmware image growth because this function runs infrequently.
DShow the path is hot and whole-firmware gains justify the image-size risk.
Show answer

Answer: D Code changes need a measured bottleneck and regression gate.

iotclass.org

Retrieval practice

Recall check 2 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q2A profile shows firmware spends much of its active window waiting for a peripheral transfer to complete. Which software optimization should be evaluated first?

ARewrite loops because CPU execution dominates the active window with peripheral waits.
BIncrease logging during waits to expose the transfer in traces.
CKeep polling because the source code is easier to understand.
DUse event-driven transfers so the CPU can sleep while waiting.
Show answer

Answer: D Optimization follows the measured bottleneck.

iotclass.org

Retrieval practice

Recall check 3 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q3How should the team compare the two firmware builds before choosing one?

AKeep it because shorter active time should save battery charge
BCheck hot-function timing first and defer the larger regression suite
CReturn to the size-focused build because it leaves more OTA space
DCompare size, timing, full-cycle current, and OTA limits first.
Show answer

Answer: D Software optimization is multidimensional.

iotclass.org

Retrieval practice

Recall check 4 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q4Why does an event-driven firmware structure usually beat a polling loop on battery life by a large margin?

AEvent-driven code executes fewer total instructions per event.
BPolling uses a slower clock, which wastes energy.
CPolling holds the processor active to keep checking.
DEvent-driven designs never need to process anything.
Show answer

Answer: C Polling keeps the core active at milliamps while event-driven firmware sleeps at microamps and wakes only on real events.

iotclass.org

Retrieval practice

Recall check 5 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q5A node handles about 10 events per hour, each 5 ms at 8 mA, and can sleep at 10 uA. What is the approximate average current if it is event-driven rather than polling at 8 mA?

AAbout 8 mA, treating event-driven operation as full-time polling.
BAbout 10.1 µA, close to the 10 µA sleep floor.
CAbout 4 mA, taking half the polling current without duty time.
DAbout zero, omitting the nonzero current between events.
Show answer

Answer: B The bursts contribute 0.4 mA-s per hour, or about 0.11 uA averaged. Add the 10 uA sleep floor for roughly 10.1 uA total, about 800x below 8 mA polling.

iotclass.org

Retrieval practice

Recall check 6 of 6

Battery Bruno says: answer from memory, then check your reasoning.

Q6A firmware author changes fixed-interval reporting to use delay(1000) between reports expecting big energy savings, but the average current barely drops. A trace shows the processor stays active during the one-second delay on this platform. Why?

Adelay() is busy-waiting; a real sleep call needs a timer wake.
BThe reporting interval is too short for a timer wake to help.
Cdelay() already enters deep sleep, so the battery estimate is wrong.
DBattery self-discharge is dominating the one-second interval.
Show answer

Answer: A In this scenario, delay() uses a busy-wait implementation, so the core stays active for the whole second.

iotclass.org

Print reference

Answers 1 of 2

Answer key.

  1. D · Code changes need a measured bottleneck and regression gate.
  2. D · Optimization follows the measured bottleneck.
  3. D · Software optimization is multidimensional.
  4. C · Polling keeps the core active at milliamps while event-driven firmware sleeps at microamps and wakes only on real events.
  5. B · The bursts contribute 0.4 mA-s per hour, or about 0.11 uA averaged. Add the 10 uA sleep floor for roughly 10.1 uA total, about 800x below 8 mA polling.
iotclass.org

Print reference

Answers 2 of 2

Answer key.

  1. A · In this scenario, delay() uses a busy-wait implementation, so the core stays active for the whole second.
iotclass.org