---
title: "global history: 반반인 분기의 답이 앞 분기에 숨어 있을 때"
author: "브레이브브라우저쓰자"
published_at: "2026-10-13T23:04:02.532Z"
updated_at: "2026-10-06T00:28:09.919Z"
tags: ["global history"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/global-history-%EB%B0%98%EB%B0%98%EC%9D%B8-%EB%B6%84%EA%B8%B0%EC%9D%98-%EB%8B%B5%EC%9D%B4-%EC%95%9E-%EB%B6%84%EA%B8%B0%EC%97%90-%EC%88%A8%EC%96%B4-%EC%9E%88%EC%9D%84-%EB%95%8C"
ai_assisted: true
---

# global history: 반반인 분기의 답이 앞 분기에 숨어 있을 때

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/global-history-%EB%B0%98%EB%B0%98%EC%9D%B8-%EB%B6%84%EA%B8%B0%EC%9D%98-%EB%8B%B5%EC%9D%B4-%EC%95%9E-%EB%B6%84%EA%B8%B0%EC%97%90-%EC%88%A8%EC%96%B4-%EC%9E%88%EC%9D%84-%EB%95%8C)

어떤 분기는 혼자 보면 taken과 not-taken이 정확히 반반이다. 그런데 바로 앞 분기의 결과를 알려 주면 다음 방향을 거의 확실하게 알 수 있다. 분기 예측에서 global history가 제공하는 정보는 이런 차이에 있다. 해당 분기의 과거 빈도에 더해, 최근 프로그램이 어떤 갈림길을 지나왔는지를 문맥으로 사용하는 것이다.

전역 이력은 프로그램의 의미를 해석하는 장치가 아니다. 최근 분기 결과를 비트열로 보관하고, 그 비트열과 명령 주소로 예측 표를 선택한다. 적절한 상관관계가 있으면 같은 PC의 여러 상황을 나눌 수 있지만, 관계없는 분기까지 섞이면 다른 충돌이 생긴다.

## 반반인 분기를 두 가지 상황으로 나눈다

가상의 코드에서 분기 A가 입력 flag에 따라 T 또는 N이 되고, 곧이어 분기 B도 같은 flag로 같은 방향을 선택한다고 하자. 그 사이에 다른 분기는 없으며 관심 구간에서는 A와 B가 번갈아 나타난다. flag의 참과 거짓이 같은 횟수라면 B 자체의 taken 비율은 50%다.

B의 PC마다 항상 한 방향을 고르는 단순한 표는 두 상황을 구분하지 못한다. 반면 직전 분기 결과 한 비트를 문맥으로 사용하면 B 앞의 이력 T인 경우 B도 T, 이력 N인 경우 B도 N이라는 두 기록을 학습할 수 있다. 두 문맥이 별도 entry를 갖고 충분히 학습되었다면 이 가상 패턴의 B는 모두 맞힐 수 있다.

이것은 모든 PC 기반 예측기가 50%를 넘을 수 없다는 주장은 아니다. 해당 분기 자체의 순서를 기억하는 다른 방식도 있을 수 있다. 이 예가 보여 주는 것은 B의 전체 빈도가 숨긴 조건부 정보를 A의 최근 결과가 드러낸다는 사실이다. 어떤 문맥을 기록해야 하는지는 코드의 상관관계에 달려 있다.

BOOM은 Global History Register를 최근 분기들의 결과로 설명하고, GShare에서 그 이력과 명령 주소를 해시하여 2비트 표를 선택한다고 설명한다. 주소와 이력의 XOR는 간단한 대표 방식이다. 이력 자체가 정답을 담는 것이 아니라, 같은 분기를 어떤 과거와 함께 관측했는지에 맞는 기록을 찾도록 돕는다. [BOOM BPD, GHR 및 GShare](https://docs.boom-core.org/en/latest/sections/branch-prediction/backing-predictor.html#the-gshare-predictor)

## 상황을 나누면서 다른 상황을 다시 합친다

표가 무한히 클 수는 없다. 가상의 8-entry GShare에서 index를 PC의 선택한 세 비트 P와 3비트 이력 H의 XOR로 정하자. P=001, H=010이면 index는 011이다. 다른 분기의 P=101, H=110도 index는 011이다.

두 상황의 실제 결과가 서로 반대라면 같은 카운터를 다른 방향으로 훈련한다. global history를 도입했다고 aliasing이 사라진 것이 아니다. PC만으로 나누던 상황을 이력까지 사용하여 다시 분배한 것이다. 어떤 충돌이 줄고 어떤 충돌이 늘었는지를 표 크기와 입력 패턴에서 평가해야 한다.

이력 길이 역시 무조건 길수록 좋지 않다. 앞의 A와 B 사이에 관련 없는 분기 C가 끼면, 직전 한 비트는 A가 아니라 C의 결과다. A의 정보를 유지하려면 더 긴 이력이 필요할 수 있다. 반대로 관련 없는 비트까지 긴 이력에 포함하면, 같은 B의 의미 있는 상황을 많은 문맥으로 잘게 나누어 학습이 늦어질 수 있다. 작은 표에 그것들을 해시하면 다시 공유가 생긴다.

최근 방향의 비트열은 어느 분기가 그 비트를 만들었는지를 전부 기록하지 않는다. 따라서 같은 비트열이라도 실제로 거쳐 온 분기 PC들이 다를 수 있다. 단순한 결과 이력을 프로그램 실행 경로의 완전한 이름처럼 취급하면 표현력의 한계를 놓친다.

## 이력을 언제 썼는지도 정보의 일부다

고성능 파이프라인에서는 앞 분기의 실제 결과가 확정되기 전에 뒷 분기를 예측한다. 실제 결과만 기다려 이력을 갱신하면 B가 조회할 때 필요한 최신 A의 정보가 아직 없을 수 있다. 그래서 예측한 방향으로 이력을 먼저 갱신하는 방식을 쓴다. 그 정보는 신선하지만 확정된 사실은 아니다.

BOOM 문서는 GHR을 투기적으로 갱신하고 오예측 때 snapshot을 이용하여 올바른 이력으로 복구하는 이유를 설명한다. 이는 카운터의 학습 시점과 구별된다. 최신 문맥을 조회에 제공하는 일과 틀린 경로의 결과로 표를 훈련하지 않는 일을 따로 관리해야 한다. [BOOM BPD, Managing the GHR 및 Updating](https://docs.boom-core.org/en/latest/sections/branch-prediction/backing-predictor.html#managing-the-global-history-register-ghr)

따라서 이력 길이를 비교하는 실험에는 표 크기, 해시, 초기화, 학습 시점이 함께 고정되어야 한다. 가상으로 실제 결과를 즉시 주입한 예측 모델의 정확도를 투기적 실행을 포함한 회로의 결과와 곧바로 비교하기도 어렵다.

global history의 역할은 최근 비트를 많이 쌓는 데 그치지 않는다. 단독 빈도에서 보이지 않는 분기 사이의 관계를 예측 표의 문맥으로 바꾸는 것이다. 좋은 이력은 필요한 관계를 남기고, 표가 감당할 수 있는 형태로 구분된다. 그 관계가 없는 입력에서는 추가된 이력도 추가 정보라는 보장이 없다.

