Project 11.10 Section 11 ⚡ Embedded Relevance: High std::deque std::list Cache Locality Pointer Chasing L1 Data Cache

11.10 Contiguous Memory vs Pointer Chasing and Node Allocation Overhead

Executive Summary: Comparing non-contiguous containers (std::deque, std::list) against contiguous arrays. We examine CPU cache lines, L1 cache misses from pointer chasing, and node memory overhead in embedded architectures.

💻 1. Annotated Source Code

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Person {
	public:
		string name;
		int age;

		Person(string name, int age) : name(name), age(age) {
			cout << "Constructed: " << name << endl;
		}

		Person(const Person& other) {
			name = other.name;
			age = other.age;
			cout << "Copied: " << name << endl;
		}
};


int main() {
	vector<Person> people;

	cout << "\nUsing push back:" << endl;
	Person p1("Alice", 30);
	people.push_back(p1);

	cout << "\nUsing emplace back:" << endl;
	people.emplace_back("Bob", 40);


	return 0;
}

📐 2. Architecture & UML Class Model

📐 Associative STL Trees (std::set, std::map) Architecture
+ Public - Private # Protected
<<template class>> std::set<Key> Red-Black Tree
-_M_t : _Rb_tree<Key, Key, ...>
+insert(val: const Key&) : pair<iterator, bool>
+find(k: const Key&) : iterator
<<template class>> std::map<Key, Value> Red-Black KV Tree
-_M_tree : _Rb_tree<Key, pair<const Key, Value>, ...>
+operator[](k: const Key&) : Value&
+find(k: const Key&) : iterator

📚 3. Core C++ Concepts Deep-Dive

1. Linked Lists vs Double-Ended Queues

std::list is a doubly linked list where each node contains pointers to next and previous nodes. std::deque is a map of fixed-size chunks.

⚡ 4. Embedded Systems & Hardware Reality

1. Cache Line Penalties and Memory Overhead

On modern MCUs with caches (e.g. ARM Cortex-M7), iterating through contiguous arrays (std::vector / std::array) triggers pre-fetching. In contrast, std::list causes constant L1 cache misses due to scattered heap node addresses (pointer chasing).

💡 5. Production-Ready Embedded Refactoring

💡 Production-Ready Refactor
// Prefer contiguous std::array for maximum CPU cache throughput
#include <array>
#include <iostream>

void processSensorArray() {
    std::array<int, 64> fastData;
    // Sequential memory access maximizes cache line utilization
}

📝 Knowledge Verification Quiz

Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.

Q1. Why does std::vector almost always outperform std::list for sequential iteration on modern microcontrollers?
A std::vector utilizes CPU register caches.
B Contiguous memory layout provides optimal CPU cache locality and spatial prefetching, avoiding pointer chasing.
C std::list cannot store integers.
D std::vector uses assembly language.
Detailed Explanation: Contiguous storage means adjacent elements reside in the same CPU cache line, whereas linked list nodes are scattered across RAM, causing pipeline stalls on cache misses.