bpred 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python: ["3.10", "3.11", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python }}
19
+ - run: pip install -e ".[dev]"
20
+ - run: ruff check .
21
+ - run: mypy src
22
+ - run: pytest -q
bpred-0.2.0/.gitignore ADDED
@@ -0,0 +1,42 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ *.so
7
+ *.egg
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ .eggs/
12
+ .cache/
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ .pytest_cache/
16
+ htmlcov/
17
+ .coverage
18
+ coverage.xml
19
+
20
+ # Virtual environments
21
+ .venv/
22
+ venv/
23
+ env/
24
+ ENV/
25
+
26
+ # uv
27
+ uv.lock
28
+
29
+ # Distribution / packaging
30
+ *.tar.gz
31
+ *.whl
32
+ MANIFEST
33
+
34
+ # IDEs
35
+ .idea/
36
+ .vscode/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+
41
+ # macOS
42
+ .DS_Store
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2026-06-17
9
+
10
+ ### Added
11
+
12
+ - `PerceptronPredictor`: Jimenez and Lin (2001) table of integer-weight perceptrons.
13
+ Captures linearly-separable history patterns that bimodal and gshare cannot learn.
14
+ Constructor: `PerceptronPredictor(history_length=H, table_size=N)`.
15
+ Exported from `bpred` top-level package.
16
+
17
+ ### Notes
18
+
19
+ - PyPI publish is queued behind the new-project creation quota (currently
20
+ rate-limited). Build artifact passes `twine check`. Publish will follow once
21
+ the quota resets.
22
+
23
+ ## [0.1.0] - 2026-06-17
24
+
25
+ ### Added
26
+
27
+ - `SaturatingCounter`: n-bit saturating counter building block.
28
+ - `BimodalPredictor`: Smith (1981) table of saturating counters indexed by PC.
29
+ - `GsharePredictor`: McFarling (1993) global-history XOR predictor.
30
+ - `TournamentPredictor`: McFarling (1993) / Alpha 21264-style meta-selecting predictor.
31
+ - `run_trace`, `accuracy`, `mispredictions`: trace-driven simulation utilities.
32
+ - `bpred` CLI supporting bimodal, gshare, and tournament subcommands.
33
+ - Full mypy strict and ruff linting.
34
+ - CI on Python 3.10, 3.11, 3.12, 3.13.
bpred-0.2.0/CLAUDE.md ADDED
@@ -0,0 +1,59 @@
1
+ # bpred -- Project Instructions
2
+
3
+ ## What this is
4
+
5
+ Pure-Python simulator of classical CPU branch predictors (bimodal, gshare,
6
+ tournament). Zero runtime dependencies. Target: Python 3.10+.
7
+
8
+ ## Source layout
9
+
10
+ ```
11
+ src/bpred/
12
+ counter.py -- SaturatingCounter (shared building block)
13
+ bimodal.py -- BimodalPredictor
14
+ gshare.py -- GsharePredictor
15
+ tournament.py -- TournamentPredictor + BranchPredictor protocol
16
+ trace.py -- run_trace, accuracy, mispredictions, TraceResult
17
+ cli.py -- argparse CLI entry point
18
+ __init__.py -- public re-exports
19
+ py.typed -- PEP 561 marker
20
+ tests/
21
+ test_counter.py -- golden FSM values + property tests for counter
22
+ test_bimodal.py
23
+ test_gshare.py
24
+ test_tournament.py
25
+ test_property.py -- property-style exhaustive tests
26
+ test_trace.py
27
+ ```
28
+
29
+ ## Conventions
30
+
31
+ - No default parameter values anywhere. All parameters are keyword-only.
32
+ - Strict mypy passes on all files in src/.
33
+ - ruff lint set: E, F, I, UP, ANN.
34
+ - No runtime dependencies (stdlib only).
35
+ - No em dash characters in any file.
36
+ - Commits: `type(scope): description`. No Co-authored-by trailers.
37
+
38
+ ## Running checks
39
+
40
+ ```bash
41
+ pytest -q
42
+ ruff check .
43
+ mypy src
44
+ uv build
45
+ uv run --with twine twine check dist/*
46
+ ```
47
+
48
+ ## Predictor invariants
49
+
50
+ - SaturatingCounter value always stays in [0, max_value].
51
+ - predict() is a pure function of current state.
52
+ - Gshare GHR is updated AFTER recording the prediction.
53
+ - Tournament: chooser updated only when sub-predictors disagree.
54
+ - Tournament: both sub-predictors always updated regardless of chooser.
55
+
56
+ ## What NOT to assert in tests
57
+
58
+ Do NOT assert that tournament is never worse than both sub-predictors on a
59
+ single prediction. A meta-selector can choose the wrong sub-predictor.
@@ -0,0 +1,39 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as contributors and maintainers pledge to make participation in this project
6
+ a harassment-free experience for everyone, regardless of age, body size,
7
+ disability, ethnicity, sex characteristics, gender identity and expression,
8
+ level of experience, education, socioeconomic status, nationality, personal
9
+ appearance, race, religion, or sexual identity and orientation.
10
+
11
+ ## Our Standards
12
+
13
+ Examples of behaviour that contributes to a positive environment:
14
+
15
+ - Using welcoming and inclusive language.
16
+ - Being respectful of differing viewpoints and experiences.
17
+ - Gracefully accepting constructive criticism.
18
+ - Focusing on what is best for the community.
19
+ - Showing empathy toward other community members.
20
+
21
+ Examples of unacceptable behaviour:
22
+
23
+ - The use of sexualised language or imagery.
24
+ - Trolling, insulting or derogatory comments, and personal or political attacks.
25
+ - Public or private harassment.
26
+ - Publishing others' private information without explicit permission.
27
+ - Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting.
29
+
30
+ ## Enforcement
31
+
32
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be
33
+ reported by opening a GitHub issue or contacting the maintainer directly.
34
+ All complaints will be reviewed and investigated promptly and fairly.
35
+
36
+ ## Attribution
37
+
38
+ This Code of Conduct is adapted from the
39
+ [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,45 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in contributing to `bpred`.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/amaar-mc/bpred
9
+ cd bpred
10
+ pip install -e ".[dev]"
11
+ ```
12
+
13
+ ## Running checks
14
+
15
+ ```bash
16
+ pytest -q # tests
17
+ ruff check . # linting
18
+ mypy src # type checking
19
+ ```
20
+
21
+ All three must pass before opening a pull request.
22
+
23
+ ## Guidelines
24
+
25
+ - Zero runtime dependencies. All new code must work with the Python standard
26
+ library only.
27
+ - Strict typing. All public functions must have complete type annotations, and
28
+ `mypy --strict` must pass.
29
+ - No default parameter values on public APIs. All parameters must be explicit
30
+ keyword arguments.
31
+ - Test behaviour, not implementation. New predictors must come with tests
32
+ covering correctness on structured traces, not just "it ran without crashing."
33
+ - Bug fixes: add a failing test first, then fix the bug.
34
+
35
+ ## Pull requests
36
+
37
+ - Open an issue first for significant changes.
38
+ - Keep commits focused. One logical change per commit.
39
+ - Commit message format: `type(scope): description` (e.g.
40
+ `feat(gshare): add history_bits validation`).
41
+ - Do not add `Co-authored-by` trailers or automated tool footers.
42
+
43
+ ## Code of Conduct
44
+
45
+ See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
bpred-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Amaar Chughtai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bpred-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.4
2
+ Name: bpred
3
+ Version: 0.2.0
4
+ Summary: Pure-Python simulator of classical CPU branch predictors: bimodal, gshare, and tournament
5
+ Project-URL: Homepage, https://github.com/amaar-mc/bpred
6
+ Project-URL: Repository, https://github.com/amaar-mc/bpred
7
+ Project-URL: Issues, https://github.com/amaar-mc/bpred/issues
8
+ Author-email: Amaar Chughtai <amaardevx@gmail.com>
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Amaar Chughtai
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: bimodal,branch-prediction,computer-architecture,cpu-simulator,education,gshare
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Intended Audience :: Education
34
+ Classifier: Intended Audience :: Science/Research
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Topic :: Education
42
+ Classifier: Topic :: Scientific/Engineering
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.10
45
+ Provides-Extra: dev
46
+ Requires-Dist: mypy>=1.10; extra == 'dev'
47
+ Requires-Dist: pytest>=8; extra == 'dev'
48
+ Requires-Dist: ruff>=0.4; extra == 'dev'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # bpred
52
+
53
+ <p align="center">
54
+ <img src="assets/logo.png" alt="bpred logo" width="160">
55
+ </p>
56
+
57
+ Pure-Python simulator of classical CPU branch predictors for computer architecture education.
58
+
59
+ Implements four predictors from first principles with zero runtime dependencies:
60
+
61
+ - **Bimodal** (Smith 1981) -- a table of n-bit saturating counters indexed by PC.
62
+ - **Gshare** (McFarling 1993) -- PC XOR global-history register indexes 2-bit counters.
63
+ - **Tournament** (McFarling 1993 / Alpha 21264) -- a meta-selector combining local and global sub-predictors.
64
+ - **Perceptron** (Jimenez and Lin 2001) -- a table of integer-weight perceptrons that can learn linearly-separable history patterns bimodal and gshare cannot capture.
65
+
66
+ Part of the same open-source computer architecture education series as [tomasulo](https://github.com/amaar-mc/tomasulo) (out-of-order execution) and scoreboarding.
67
+
68
+ ## Install
69
+
70
+ ```bash
71
+ pip install bpred
72
+ ```
73
+
74
+ PyPI publication is pending; install from source in the meantime:
75
+
76
+ ```bash
77
+ git clone https://github.com/amaar-mc/bpred
78
+ cd bpred
79
+ pip install -e ".[dev]"
80
+ ```
81
+
82
+ ## Python API
83
+
84
+ ```python
85
+ from bpred import BimodalPredictor, GsharePredictor, PerceptronPredictor, TournamentPredictor
86
+ from bpred import run_trace, accuracy, mispredictions
87
+
88
+ # Bimodal: 2-bit counters, 1024-entry table
89
+ pred = BimodalPredictor(counter_bits=2, table_size=1024)
90
+
91
+ # Gshare: 10-bit history, 1024-entry table
92
+ pred = GsharePredictor(history_bits=10, table_size=1024)
93
+
94
+ # Tournament
95
+ from bpred import BimodalPredictor, GsharePredictor
96
+ local = BimodalPredictor(counter_bits=2, table_size=1024)
97
+ global_ = GsharePredictor(history_bits=10, table_size=1024)
98
+ pred = TournamentPredictor(local=local, global_=global_, meta_bits=2)
99
+
100
+ # Perceptron: 12-bit history, 1024-entry table
101
+ pred = PerceptronPredictor(history_length=12, table_size=1024)
102
+
103
+ # Feed a trace
104
+ trace = [(0x1000, True), (0x1004, False), (0x1008, True)]
105
+ result = run_trace(pred, trace=trace)
106
+ print(accuracy(trace_result=result)) # e.g. 0.6667
107
+ print(mispredictions(trace_result=result)) # e.g. 1
108
+ ```
109
+
110
+ ### Why use the perceptron predictor?
111
+
112
+ Bimodal and gshare each use a single scalar counter per table entry, so they
113
+ can only learn the *average* bias of a branch. When the taken/not-taken
114
+ outcome correlates with a specific combination of recent history bits (a
115
+ linearly-separable pattern), those predictors plateau.
116
+
117
+ The perceptron predictor maintains a weight vector per entry. The dot product
118
+ of those weights with the history vector expresses arbitrary linear functions
119
+ over H history bits. This lets it learn, for example, "taken when the last
120
+ 4 branches were all taken" or "taken on every other iteration" -- patterns
121
+ that require tracking distinct history bits simultaneously. The trade-off is
122
+ that the predictor needs more warm-up branches to converge and the weights
123
+ grow without bound (in simulation; hardware clamps them to a fixed-point
124
+ range).
125
+
126
+ ## CLI
127
+
128
+ ```
129
+ bpred bimodal --counter-bits 2 --table-size 1024 path/to/trace.trace
130
+ bpred gshare --history-bits 10 --table-size 1024 path/to/trace.trace
131
+ bpred tournament \
132
+ --local-predictor bimodal --local-counter-bits 2 --local-table-size 1024 \
133
+ --global-predictor gshare --global-history-bits 10 --global-table-size 1024 \
134
+ --meta-bits 2 \
135
+ path/to/trace.trace
136
+ ```
137
+
138
+ Trace file format -- one branch per line:
139
+
140
+ ```
141
+ # pc taken
142
+ 0x1000 1
143
+ 0x1004 0
144
+ 0x1008 T
145
+ 0x100c false
146
+ ```
147
+
148
+ ## Accuracy example
149
+
150
+ Running the bundled sample trace with a gshare predictor:
151
+
152
+ ```
153
+ $ bpred gshare --history-bits 4 --table-size 16 examples/sample.trace
154
+ Predictor : GsharePredictor(history_bits=4, table_size=16)
155
+ Branches : 20
156
+ Hits : 18
157
+ Misses : 2
158
+ Accuracy : 90.0000%
159
+ ```
160
+
161
+ ## Development
162
+
163
+ ```bash
164
+ pip install -e ".[dev]"
165
+ pytest -q
166
+ ruff check .
167
+ mypy src
168
+ ```
169
+
170
+ ## License
171
+
172
+ MIT. See [LICENSE](LICENSE).
bpred-0.2.0/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # bpred
2
+
3
+ <p align="center">
4
+ <img src="assets/logo.png" alt="bpred logo" width="160">
5
+ </p>
6
+
7
+ Pure-Python simulator of classical CPU branch predictors for computer architecture education.
8
+
9
+ Implements four predictors from first principles with zero runtime dependencies:
10
+
11
+ - **Bimodal** (Smith 1981) -- a table of n-bit saturating counters indexed by PC.
12
+ - **Gshare** (McFarling 1993) -- PC XOR global-history register indexes 2-bit counters.
13
+ - **Tournament** (McFarling 1993 / Alpha 21264) -- a meta-selector combining local and global sub-predictors.
14
+ - **Perceptron** (Jimenez and Lin 2001) -- a table of integer-weight perceptrons that can learn linearly-separable history patterns bimodal and gshare cannot capture.
15
+
16
+ Part of the same open-source computer architecture education series as [tomasulo](https://github.com/amaar-mc/tomasulo) (out-of-order execution) and scoreboarding.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install bpred
22
+ ```
23
+
24
+ PyPI publication is pending; install from source in the meantime:
25
+
26
+ ```bash
27
+ git clone https://github.com/amaar-mc/bpred
28
+ cd bpred
29
+ pip install -e ".[dev]"
30
+ ```
31
+
32
+ ## Python API
33
+
34
+ ```python
35
+ from bpred import BimodalPredictor, GsharePredictor, PerceptronPredictor, TournamentPredictor
36
+ from bpred import run_trace, accuracy, mispredictions
37
+
38
+ # Bimodal: 2-bit counters, 1024-entry table
39
+ pred = BimodalPredictor(counter_bits=2, table_size=1024)
40
+
41
+ # Gshare: 10-bit history, 1024-entry table
42
+ pred = GsharePredictor(history_bits=10, table_size=1024)
43
+
44
+ # Tournament
45
+ from bpred import BimodalPredictor, GsharePredictor
46
+ local = BimodalPredictor(counter_bits=2, table_size=1024)
47
+ global_ = GsharePredictor(history_bits=10, table_size=1024)
48
+ pred = TournamentPredictor(local=local, global_=global_, meta_bits=2)
49
+
50
+ # Perceptron: 12-bit history, 1024-entry table
51
+ pred = PerceptronPredictor(history_length=12, table_size=1024)
52
+
53
+ # Feed a trace
54
+ trace = [(0x1000, True), (0x1004, False), (0x1008, True)]
55
+ result = run_trace(pred, trace=trace)
56
+ print(accuracy(trace_result=result)) # e.g. 0.6667
57
+ print(mispredictions(trace_result=result)) # e.g. 1
58
+ ```
59
+
60
+ ### Why use the perceptron predictor?
61
+
62
+ Bimodal and gshare each use a single scalar counter per table entry, so they
63
+ can only learn the *average* bias of a branch. When the taken/not-taken
64
+ outcome correlates with a specific combination of recent history bits (a
65
+ linearly-separable pattern), those predictors plateau.
66
+
67
+ The perceptron predictor maintains a weight vector per entry. The dot product
68
+ of those weights with the history vector expresses arbitrary linear functions
69
+ over H history bits. This lets it learn, for example, "taken when the last
70
+ 4 branches were all taken" or "taken on every other iteration" -- patterns
71
+ that require tracking distinct history bits simultaneously. The trade-off is
72
+ that the predictor needs more warm-up branches to converge and the weights
73
+ grow without bound (in simulation; hardware clamps them to a fixed-point
74
+ range).
75
+
76
+ ## CLI
77
+
78
+ ```
79
+ bpred bimodal --counter-bits 2 --table-size 1024 path/to/trace.trace
80
+ bpred gshare --history-bits 10 --table-size 1024 path/to/trace.trace
81
+ bpred tournament \
82
+ --local-predictor bimodal --local-counter-bits 2 --local-table-size 1024 \
83
+ --global-predictor gshare --global-history-bits 10 --global-table-size 1024 \
84
+ --meta-bits 2 \
85
+ path/to/trace.trace
86
+ ```
87
+
88
+ Trace file format -- one branch per line:
89
+
90
+ ```
91
+ # pc taken
92
+ 0x1000 1
93
+ 0x1004 0
94
+ 0x1008 T
95
+ 0x100c false
96
+ ```
97
+
98
+ ## Accuracy example
99
+
100
+ Running the bundled sample trace with a gshare predictor:
101
+
102
+ ```
103
+ $ bpred gshare --history-bits 4 --table-size 16 examples/sample.trace
104
+ Predictor : GsharePredictor(history_bits=4, table_size=16)
105
+ Branches : 20
106
+ Hits : 18
107
+ Misses : 2
108
+ Accuracy : 90.0000%
109
+ ```
110
+
111
+ ## Development
112
+
113
+ ```bash
114
+ pip install -e ".[dev]"
115
+ pytest -q
116
+ ruff check .
117
+ mypy src
118
+ ```
119
+
120
+ ## License
121
+
122
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,22 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ |---------|-----------|
7
+ | 0.1.x | Yes |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ `bpred` is a pure-Python educational simulator with zero runtime dependencies
12
+ and no network access, secrets handling, or persistent storage. The attack
13
+ surface is minimal.
14
+
15
+ If you discover a security vulnerability (for example, a path traversal issue
16
+ in the CLI trace-file parser), please report it by opening a GitHub issue
17
+ marked with the `security` label. For sensitive matters that should not be
18
+ public, contact the maintainer directly via the email address listed in
19
+ `pyproject.toml`.
20
+
21
+ We aim to acknowledge reports within 72 hours and to release a fix within
22
+ 14 days for confirmed vulnerabilities.
Binary file
@@ -0,0 +1,101 @@
1
+ # Predictor Architecture
2
+
3
+ This document describes the three branch predictors implemented in `bpred`,
4
+ their algorithmic basis, and the primary academic references.
5
+
6
+ ## References
7
+
8
+ - J. E. Smith, "A study of branch prediction strategies," in _Proceedings of
9
+ the 8th Annual Symposium on Computer Architecture (ISCA)_, pp. 135-148, 1981.
10
+ - S. McFarling, "Combining Branch Predictors," WRL Technical Note TN-36,
11
+ Digital Equipment Corporation Western Research Laboratory, June 1993.
12
+
13
+ ---
14
+
15
+ ## Saturating Counter
16
+
17
+ A saturating counter is the base component of all three predictors. An n-bit
18
+ counter holds a value in [0, 2^n - 1]. It predicts _taken_ when the value is
19
+ >= 2^(n-1) and _not-taken_ otherwise. Taken outcomes increment the counter
20
+ toward the maximum; not-taken outcomes decrement it toward zero. At either
21
+ extreme the counter saturates rather than wrapping.
22
+
23
+ The 2-bit variant (n=2) is the classic design from Smith (1981). Its four
24
+ states are:
25
+
26
+ | Value | Name | Predict |
27
+ |-------|-----------------|---------|
28
+ | 0 | Strongly Not-Taken (SN) | not-taken |
29
+ | 1 | Weakly Not-Taken (WN) | not-taken |
30
+ | 2 | Weakly Taken (WT) | taken |
31
+ | 3 | Strongly Taken (ST) | taken |
32
+
33
+ Two consecutive mispredictions are required to flip the prediction, providing
34
+ hysteresis against noise.
35
+
36
+ ---
37
+
38
+ ## Bimodal Predictor
39
+
40
+ **Reference:** Smith (1981).
41
+
42
+ A flat table of `table_size` saturating counters of `counter_bits` bits each.
43
+ The table is indexed by `pc mod table_size`. On every branch:
44
+
45
+ 1. Predict using the counter at index `pc mod table_size`.
46
+ 2. Update that counter with the actual outcome.
47
+
48
+ Multiple branches whose PCs map to the same entry share a counter (aliasing).
49
+ Larger tables reduce aliasing at the cost of hardware area.
50
+
51
+ ---
52
+
53
+ ## Gshare Predictor
54
+
55
+ **Reference:** McFarling (1993).
56
+
57
+ Gshare extends the bimodal idea by incorporating global correlation. A global
58
+ history register (GHR) of `history_bits` bits records the outcomes of the most
59
+ recent branches across the entire program. The table index is:
60
+
61
+ ```
62
+ index = (pc XOR ghr) mod table_size
63
+ ```
64
+
65
+ Each entry is a 2-bit saturating counter. After every branch the actual
66
+ outcome is shifted into the GHR (MSB first), discarding outcomes older than
67
+ `history_bits`.
68
+
69
+ XOR hashing distributes entries more uniformly across the table than either
70
+ PC or GHR alone, and exploits cross-branch correlation to improve accuracy
71
+ on correlated loops and function-call patterns.
72
+
73
+ ---
74
+
75
+ ## Tournament Predictor
76
+
77
+ **Reference:** McFarling (1993); Alpha 21264 implementation.
78
+
79
+ A tournament predictor combines two sub-predictors (a local and a global) using
80
+ a meta-selector table. The meta-selector contains saturating counters of
81
+ `meta_bits` bits that choose which sub-predictor to trust for each PC.
82
+
83
+ ### Prediction
84
+
85
+ 1. Look up the chooser counter at `pc mod chooser_size`.
86
+ 2. If counter value < threshold (2^(meta_bits - 1)), use the _local_ predictor.
87
+ 3. Otherwise use the _global_ predictor.
88
+
89
+ ### Update (Alpha 21264 scheme)
90
+
91
+ Both sub-predictors are always updated with the actual outcome. The chooser is
92
+ updated only when the two sub-predictors _disagree_:
93
+
94
+ - If only the local predictor was correct: decrement the chooser (bias toward local).
95
+ - If only the global predictor was correct: increment the chooser (bias toward global).
96
+ - If both or neither was correct: no chooser update.
97
+
98
+ This approach concentrates meta-selector learning signal on cases where the
99
+ choice actually matters.
100
+
101
+ The chooser table size equals `max(local.table_size, global_.table_size)`.