基于CNN的预测器 “BranchNet: A Convolutional Neural Network to Predict Hard-To-Predict Branches”(2020)

MPKI千条指令的预测失误率。

MPPKI千条指令的预测失误惩罚。

全局历史有噪声:即全局历史包含不断改变方向的不相关分支或者历史中相关分支的位置不确定。

为什么采用CNN实现预测器

  • 最先进的分支预测器TAGE在识别嘈杂的全局分支历史深处的相关分支方面仍然效率低下。类似TAGE的预测器必须为每个可能的历史模式专用唯一的预测计数器,因此所需的预测计数器随着历史大小呈指数级增长,且需要很长的时间预热这些大量的条目,使得当相关分支出现在嘈杂的历史深处时,该方法不可行。而基于CNN的预测器可以学习忽略相关分支,从而克服这一点。除此之外,类似TAGE的预测器永远无法将其预测推广到看不见的历史模式
  • 像TAGE和感知器这样的传统分支预测器被设计为在线更新,即在运行时更新,因此,其更新算法须简单、便宜且快速,以适应执行阶段的行为。但训练时间和处理能力的限制也使得在线分支预测器难以学习分支历史中的复杂相关性,而为了学习这些相关性,就需采用更复杂的预测机制,而这需要更多计算量大的训练算法和额外的编译器支持

缺点

CNN并不能预测所有的分支,在全局历史中没有分支可以提供关于目标分支结果的任何信息时,例如一些分支依赖与很久以前存储在内存中的数据时,仅使用全局分支历史作为输入,CNN无法从中学习到预测策略。

结构特点

  • 离线训练CNN(即在编译时),BranchNet不太依赖与训练数据的代表性,而更多地依赖于覆盖率。关键是训练集包括足够多的不同分支行为的例子,即暴露足够的控制流路径来检测输入相关地分支相关性,这些相关性可以推广到看不到的输入
  • 输入:全局分支和路径历史输入(包括分支地址和跳转方向)嵌入向量(我们embedding)。
  • 卷积层:卷积宽度控制构成要素的相邻项目的数量。对于分支预测,考虑的相邻项目是分支/路径历史中的相邻条目;每个filter识别历史中特定相关分支模式的存在,通过向filter的相应输出通道输出非零值来标记其位置。
  • 总和池化层:池化层的输出指示在每个通道中识别的特征的出现计数。通过将卷积输出通道的相邻输出合成总和来降低后续层的计算要求,代价是丢弃已识别特征的细粒度位置。
  • 全连接层:将识别的特征计数映射到预测。

CNN预测一个H2P分支的例子

图3中分支B(line 11 循环退出的分支指令)依赖于x的值,但由于循环迭代导致真正与其相关的分支隐藏在较深的历史中,导致基于模式的预测器难以预测。 

CNN可以直接从全局历史中推断出 x 和 j 的值,从而准确预测分支B。 图3中左侧的输入是预测分支B前的全局历史快照,X 是一些无关分支的pc,分支历史被编码为 one-hot 向量(图中未标出)送入卷积层。卷积宽度是1,有2条通道,channel 0 用于识别分支B未跳转的实例,channel 1 用于识别分支A未跳转的实例,使用一个和历史一样宽的求和池化层。这样求和池化层的输出就是分支A和B未跳转的实例个数,即等于 x 和 j 的值,从而可以判断。

Big-BranchNet(纯软件模型)

  • 由5个特征提取子网络(slice)和2个全连接层组成。每个slice使用一个嵌入层,一个卷积层,一个求和池化层,不同的slice对不同长度的历史长度进行操作,历史长度呈几何级数
  • 分支历史模式:连接每个分支的方向(1bit)和 pc 的低 p 个有效位,以将其表示为一个整数。假设一个slice的历史大小为H,使用PC的 p 位,则输入的历史是一个包括H个数的一维整数数组,其中每个数p+1位,在0到 2^{p+1}-1 之间。
  • 嵌入层:将输入历史中的每个分支转换成密集的数字向量。使用嵌入相比于one-hot向量能够提高BranchNet的收敛性和训练时间。E表示嵌入层的维度。
  • 卷积层:C_{i}表示slice i 输出通道的个数,K表示卷积宽度,卷积步幅为1。其中输出通道越多能识别到的分支历史中的特征越多,卷积宽度越大能识别到的相关分支序列越长。
  • 求和池化层:在每个 slice,求和池化层以步幅P_{i}下采样卷积输出。使用与每个 slice 的历史长度成正比的几何池化大小。 对于更长的历史长度,更大的池化宽度效果很好,因为历史在更深入的历史中变得更加嘈杂。通过消除历史中已识别特征的位置,对历史深处发现的特征进行积极的池化,使 BranchNet 能够抵御历史变化,即当历史中相关分支位置变化时,仍可有效预测。
  • 全连接层第一个全连接层由 N 个神经元组成。 每个神经元都连接到所有 slice 的输出。 全连接神经元后面是批量归一化和 ReLU 激活函数。 最后的全连接层由单个神经元组成,带有 Sigmoid 激活函数来进行最终预测。

 Mini-BranchNet

  • 维护卷积历史:计算BranchNet特征提取层的slice的输出涉及对全局历史中数百个分支的操作。推理机不是在预测时进行所有这些操作,而是一次处理一个输入分支,并缓冲它们的下采样卷积输出以备将来使用。称这些缓冲区为卷积历史。进行预测时,预测流水线简单地选择对应于目标分支的卷积历史,并且仅计算两个完全连接的层。
  • 用查表代替卷积:Mini-BranchNet用两步消除了所有的算术运算。在训练期间,不是将每个分支独立地嵌入卷积窗口,而是在窗口中嵌入分支的较小散列,并使用二进制化的sigmoid激活来代替ReLU。训练完成后,对于每个可能的分支散列,我们计算卷积输出(嵌入+点积+归一化+二进制化sigmoid),正好是0或1。这些二进制值现在可以存储在小型表中,迷你分支网络推理机查找这些表以获得分支散列的卷积输出。运行时不需要算术运算,消除了每次卷积运算的32维内积。

  • 使用运行求和寄存器:Mini-BranchNet使用两个设计完成求和池化输出。对于较短的历史片(slice),采用 precise pooling,精确池化使用缓冲区和运行总和寄存器来不断计算最近池化窗口的输出,并将池化输出插入到第二组缓冲区中。 结果,第二组缓冲区包含重叠窗口的池化输出。实现精确池化所需的缓冲空间随历史大小线性增大。因此,对于较长的历史片,使用sliding pooling,滑动池化在多个周期内累积窗口的池化输出,并每 P 个周期将输出插入池化缓冲区。代价是在预测时,最近的卷积输出可能没有形成完整的池化窗口。因此,历史中的一些最新分支不用于预测,并且通常池化窗口具有不确定的边界。在实践中,这不是问题,因为我们只在 Mini-BranchNet 的长历史切片中使用滑动池,它不依赖已识别特征的细粒度位置,因为它们的池宽度成比例地宽。为了考虑训练期间的滑动池化,我们随机丢弃了一些馈入长历史切片的最新分支(0 到 P-1 个分支)。这种随机化使训练算法在运行时对非确定性池边界具有弹性。

  • 量化全连接层:Mini-BranchNet 使用定点算法来计算全连接层的输出。 

Q:CNN的部分没太看懂。。。。!!!!!

结果与评价

使用 SPEC benchmarks不同的输入数据,以测试离线训练对未见过的数据的有效性。Big-BranchNet 结果证明了使用离线深度学习进行分支预测的可用空间。Mini-BranchNet 结果显示了在实际设置中使用 CNN 分支预测器的好处。

相比Tarsa-Ternary,Mini-BranchNet 架构和优化使其能够使用更长的历史记录和更深的网络,并且存储更少。

Branch Net对依赖于数据的分支无法改进;Big-BranchNet 和 Mini-BranchNet 准确率存在巨大差距

BranchNet和Bias-Free目的都是把分支历史中的不相关分支过滤掉,但前者因为离线训练而更为有效。

在不考虑实际约束的情况下将 Big-BranchNet 与 MTAGE-SC 进行了比较。我们已经证明 Big-BranchNet 在 SPEC2017 基准测试中一些最容易预测错误的分支上的表现优于 MTAGE-SC,导致 MPKI 降低了 7.6%。

为了展示 CNN 作为实际分支预测器的有效性,我们将 Mini-BranchNet 与 64KB TAGE-SC-L 进行了比较。在不增加预测延迟的情况下,Mini-BranchNet 将 MPKI 降低了 9.6%。

### YOLOv8 Detect Layer Implementation and Usage In the context of object detection, particularly within frameworks like YOLO (You Only Look Once), the detect layer plays a crucial role in predicting bounding boxes, class probabilities, and confidence scores for objects present in an image. For YOLOv8 specifically, this layer has been optimized to enhance performance while maintaining efficiency. The detect layer in YOLOv8 is implemented as part of the model's architecture where it processes feature maps generated by earlier layers such as convolutional or custom operations like SAConv2d[^1]. These processed features are then used to predict multiple attributes about detected objects including their location via bounding box coordinates along with associated classes and confidences. Here’s how one can implement and use the detect layer: #### Defining the Detection Head To define the detection head that includes the detect layer, typically involves configuring parameters related to anchors, strides, number of classes etc., which guide predictions at different scales across various levels of resolution provided by backbone network outputs. ```python import torch.nn as nn class Detect(nn.Module): stride = None # strides computed during build onnx_dynamic = False # ONNX export parameter def __init__(self, nc=80, anchors=(), ch=()): super().__init__() self.nc = nc # number of classes self.no = nc + 5 # number of outputs per anchor self.nl = len(anchors) # number of detection layers self.na = len(anchors[0]) // 2 # number of anchors self.m = nn.ModuleList( nn.Conv2d(x, self.no * self.na, 1) for x in ch) self.ia = nn.Identity() if not hasattr(self, 'ia') else self.ia self.im = nn.Identity() if not hasattr(self, 'im') else self.im ``` This code snippet defines a `Detect` module responsible for handling detections from three separate branches corresponding to varying resolutions derived from the main body of the neural net. #### Forward Pass Through Detect Layer During inference time when passing data through these models, each branch produces its own set of prediction tensors containing information regarding potential instances found inside input images after applying non-max suppression post-processing steps outside core framework logic itself. ```python def forward(self, x): z = [] # inference output for i in range(self.nl): x[i] = self.m[i](self.ia(x[i])) # conv bs, _, ny, nx = x[i].shape # batch size, _, grid_y, grid_x x[i] = ( x[i] .view(bs, self.na, self.no, ny, nx) .permute(0, 1, 3, 4, 2) .contiguous() ) if not self.training: # inference only y = x[i].sigmoid() y[..., :4] *= 2 z.append(y.view(bs, -1, self.no)) return x if self.training else (torch.cat(z, 1), x) ``` Through this method, tensor transformations prepare raw outputs suitable for further processing into final results encompassing all necessary details required for identifying targets accurately without redundancy due to overlapping candidates produced independently over distinct spatial regions covered throughout entire scene captured visually.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值