{"id":21655181,"url":"https://github.com/pseitz/bpu_trasher","last_synced_at":"2026-01-28T17:35:36.461Z","repository":{"id":258749976,"uuid":"875557396","full_name":"PSeitz/bpu_trasher","owner":"PSeitz","description":"Branch Predictor Trasher","archived":false,"fork":false,"pushed_at":"2024-10-28T03:35:55.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T21:14:25.172Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PSeitz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-20T10:00:11.000Z","updated_at":"2024-10-28T03:35:59.000Z","dependencies_parsed_at":"2024-10-21T20:05:52.479Z","dependency_job_id":null,"html_url":"https://github.com/PSeitz/bpu_trasher","commit_stats":null,"previous_names":["pseitz/bpu_trasher"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PSeitz%2Fbpu_trasher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PSeitz%2Fbpu_trasher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PSeitz%2Fbpu_trasher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PSeitz%2Fbpu_trasher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PSeitz","download_url":"https://codeload.github.com/PSeitz/bpu_trasher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480426,"owners_count":21110937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T08:30:29.414Z","updated_at":"2026-01-28T17:35:36.456Z","avatar_url":"https://github.com/PSeitz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# BPU Trasher\n\nBPU (Branch Predictor Unit) Trasher tries to trash the BPU of a processor by trying different strategies for the different components of the BPU.\n\nThis tool is useful to avoid overtraining the branch predictor unit of a processor an getting skewed results in benchmarks.\n\n### Disclaimer\nThe status of the project is still experimental. \nThe current approach is working on a high level, but the exact implementation of the BPU is not known and may vary from processor to processor.\nWhat's missing currently is a benchmark to evaluate it's effectiveness on different CPUs.\n\nYou run run an experiment in the experiment subfolder.\nSee `experiment/README.md` for more information.\n\n# BPU Concepts\n\nThe exact components of the BPU can vary from processor to processor and are not public information.\n\n## Types of Branches\nAlthough intuitively, we think of branches as conditional (e.g. `if`), for the CPU anything that changes the flow of the program is a branch.\nTherefore, there are different types of branches:\n\n1. Unconditional branches\nInstructions: `JMP`, `CALL`\n\n2. Conditional branches\nInstructions:`JNE`, `JZ`, `JE`\n\n3. Indirect Branch \nInstructions: `JMP [RAX]`\nLike Conditional branches, but the target address is not known at compile time, e.g. a virtual function call.\n\n4. Function Call\nInstructions: `CALL`\n\n5. Return from Function\nThis is an unconditional branch. It's its own type, since the BPU has a special handling for it.\nInstructions: `RET`\n\n## 2-Level Adaptive Predictor\n\nThe 2-level adaptive predictor is a common branch predictor used in modern processors.\n\nThe 2-level adaptive predictor consists of two tables:\n1. The Branch History Table (BHT)\n2. The Pattern History Table (PHT)\n\nThe BHT is a table that stores the history of the last N branches. The PHT is a table that stores the prediction of the last N branches.\nThe BHT is used to index the PHT. The PHT is used to predict the outcome of the branch.\n\n### Branch target buffer (BTB)\nThe BTB is a cache that stores the target address of the most the frequently used conditional and unconditional branches.\n\nDepending on the CPU, there may be different branch target buffers for different types of branches. For example, there may be a separate BTB for indirect branches.\n\n## Loop/Switch Counter\nThe loop counter is a special case of a branch predictor that is used to predict the number of iterations of a loop.\nAn entry in the BTB will contain information if the branch has loop behaviour and if yes, the number of iterations of the loop.\n\n## Indirect Jump Prediction\n\nIndirect jumps are jumps that are not directly to a specific address but to an address that is calculated at runtime.\nDue to polymorphism, the BTB may need to keep multiple targets. \n\nI think in Rust this would be as simple as:\n\n```rust\nfn call_me(obj: \u0026dyn MyTrait) {\n    obj.call_me(); // could have multiple targets\n}\n```\n\n## Hashing\n\nIn order to reliably trash the BPU, we need to understand how the hashing function works.\n\n\"\nThe literature recommends that the index into the pattern history table is generated by an XOR\ncombination of the history bits and the branch address. However, my experimental results\ndo not confirm such a design. The indexing function in figure 3.3 may be a more complex\nhashing function of the history and the branch address, or it may involve the branch target\naddress, BTB entry address or trace cache address.\n\nSince the indexing function is not known, it is impossible to predict whether two branches\nwill use the same entry in the pattern history table. For the same reason, I have not been\nable to measure the size of the pattern history table, but must rely on rumors in the\nliterature.\n\"\n\n## Perceptron\n\nA perceptron is a type of neural network that is used in the BPU to predict the outcome of a branch.\nIt is used in Zen 4 processors.\n\n\n### Return address stack (RAS)\n\n\n# Sources\n\nThis is an magnificient ressource:\nhttps://www.agner.org/optimize/microarchitecture.pdf\n\nDeep dive into an older architecture:\nhttp://www.ece.uah.edu/~milenka/docs/VladimirUzelac.thesis.pdf\n\nhttps://xania.org/201602/bpu-part-one\n\nhttps://www.cs.utexas.edu/~lin/papers/hpca01.pdf\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpseitz%2Fbpu_trasher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpseitz%2Fbpu_trasher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpseitz%2Fbpu_trasher/lists"}