基于BSV的高性能并行CRC硬件电路生成器

news2024/9/29 11:33:43

01、引 言

循环冗余校验码,即Cyclic Redundancy Check (CRC), 是一种在各种通信系统中广泛应用的检错机制。CRC算法的工作原理和哈希函数类似,具体来说,其对任意长度的数据计算出一段唯一的标识(校验和), 然后根据这个标识来判断该数据在传输过程中是否发生变化。CRC检错码在实际生活中有着广泛的应用,诸如网络通信,存储系统等场景下都需要CRC来保证数据传输的正确性。而不同的应用场景往往需要采用不同的CRC配置参数,同时对计算的性能也有不同的需求。例如,在基于Ethernet协议的网络传输中需要采用IEEE802-3协议所规定的CRC参数,同时需要高吞吐率的CRC实现以和网络带宽相匹配。

对于一个具体的通信系统,CRC既可以通过软件编程也可以硬件电路的形态来实现。相较于网络上丰富的软件库,开源的CRC硬件实现却相对落后,尤其是面向高性能的应用场景。例如,下述链接都提供了参数可配置的CRC硬件电路生成器,但这些实现方式都是直接将CRC算法映射到组合逻辑电路上,这往往会导致较长的组合逻辑延时进而降低电路的整体工作频率,无法满足高吞吐率的需求。

  • Easics: http://www.easics.com/webtools/crctool
  • Outputlogic: http://outputlogic.com/
  • SpinalCrypto: https://github.com/SpinalHDL/SpinalCrypto

而另外一些开源的电路实现虽然引入了流水线技术对时序进行优化,但其实现只针对某一特定的CRC配置参数,应用场景相对有限:

  • Pipelined Implementation: https://bitbucket.org/spandeygit/crc32_verilog/src/master/

针对现有CRC开源硬件实现的不足,blue-crc项目基于Bluespec SystemVerilog硬件描述语言实现了一个参数可配置同时满足高吞吐率需求的CRC硬件电路生成器。blue-crc在架构和功能上的具体特点包括:

  • 支持完整的CRC配置参数包括:polynominal (生成多项式),initial_value (初始CRC值),finalXor (与输出CRC值异或), reverseInput (是否翻转每个输入字节的比特顺序),reverseOutput (是否翻转输出CRC结果的比特顺序);
  • 标准I/O接口: 输入端支持AxiStream协议 (位宽可配置), 输出端基于valid-ready握手机制传输CRC校验和;
  • 并行计算+流水线: 每个周期可处理多个字节数据,在Xilinx xcvu9p FPGA上可达到500MHz的运行频率;
  • 高吞吐率: 在256-bit输入数据总线的配置下吞吐率可达128Gb/s;
  • 计算模式: 支持发送端CRC生成和接收CRC检测两种不同的计算模式

下文将分别从算法和架构两个方面介绍blue-crc背后的实现原理及其具体的使用方式。

02、算法原理

CRC计算的定义

生成CRC校验和本质上是在计算基于多项式的模2除法。将原始数据每个比特所确定的多项式除以一个通信双方规定好的生成多项式,得到的余数即为校验和。生成CRC校验值算法的详细定义如下:对于m-bit原始数据 

可以表示为如下多项式:

若需要生成n-bit的CRC校验值, 则通信双方需要规定一个 (n+1)-bit的生成多项式:

则原始数据的CRC校验值为多项式A(x)乘上x^n 后除以G(x)得到的余数,具体表达式为:

生成的CRC校验值附加在原始数据的尾部后传输至接收端, 即实际发出的数据为

基于CRC的生成原理,数据接收端可以采用两种不同的方式完成校验: 1) 提取出附加在发送数据尾部的校验值后生成新的CRC校验值,将该值与提取出的进行比较,如果二者相同则表明数据在传输过程中没有出错;2)由于校验值为除法运算中得到的余数,这就意味着附加上检验值后的发送数据可被生成多项式整除,因此也可以直接对接收数据进行模2除法,若得到的余数为0则表明数据传输成功。

在基于多项式的模2算术运算中,变量的取值范围只有0和1,且运算过程不存在进位或借位。因此,加减法都可以视为异或运算, 而乘除法可以由加减法构成,因此实际上也等同于一系列的异或运算。下图展示了一个具体的模2除法取余数计算CRC校验和的例子,其中原始数据为101001,生成多项式为1101。由该例子可见,模2除法的运算法则和普通的除法类似,不同点在于模2除法用异或操作替换了减法且不存在借位。

从另外一个角度理解,模二除法取余数的过程实际上是逐位地对原始数据进行缩减: 当输入数据的最高位为1时,原始数据和除数左对齐异或后移除最高位,得到下一轮缩减的输入;当最高位为0时,直接移除最高位得到下一轮缩减的输入。不断重复上述缩减步骤直至输入数据的位宽小于除数位宽,该输入值即为所求余数。根据上述取模步骤,可以很容易地将CRC算法映射到基于线性负反馈移位寄存器 (LFSR) 结构的硬件上,一种具体的实现如下图所示, 其对应的生成多项式为11011。原始数据从最高位开始逐位从Din输入,当所有数据都传入后,寄存器中的值即为所要求的校验和。

上图展示的电路结构是一种非常经典的CRC算法的硬件实现方式,其可以用极小的面积和功耗生成校验值,但由于每个周期只能处理1-bit输入数据,其很难达到较高的吞吐率。为了提升CRC校验电路的计算性能,很多面向硬件的CRC并行算法被提出。blue-crc项目的实现主要参考了论文[1]和[2]中提出的并行算法和电路架构, 并在此基础上进一步优化流水线结构以提升工作频率,同时提供了参数可配置的设计以及标准的输入输出接口。

并行算法

blue-crc项目所采用的并行算法主要是建立在模2除法(取余)运算的两个定理之上,这两个定理分别是(备注:下文所列公式中的算术运算都是在模2域下完成,即加减法都等同于异或运算):

  1. 若多项式

由定理1可知, 对于任意长度的输入数据, 都可以将其拆分成若干小段,每小段数据的CRC校验值可以独立地并行计算,然后通过异或操作将所有校验值累加在一起,即可得到完整数据对应的CRC校验值。在blue-crc的实现中,每小段数据Ai(x)的长度为8-bit, 设原始数据A(x)的总长度为8n-bit, 则: 

根据定理1,我们可以并行地计算每个输入字节Ai(x)的校验值

,然后将每个字节对应的校验和累加在一起就可得到完整数据的校验和,即

对于每个输入字节的CRC校验和的计算,除了依照算法实现对应的硬件电路, 另一种更加高效的方式是: 提前计算好8-bit数所有可能值对应的CRC输出并制作成硬件查找表,当电路运行时,以输入数据为地址从查找表中取出对应的表项即可得到校验和。若输入原始数据有n个字节,则需要制作n张长度为

的查找表,其中第

张查找表的第x个表项的值即为

的CRC校验和。

虽然有了定理1我们可以在一个周期内并行处理多个字节数据,但基于此还不能够完成CRC的硬件实现。在实际电路中数据总线的位宽是有限的,对于较长的输入数据,需要根据总线位宽将其分成多个帧并分配到多个周期进行传输。因此,我们还需要基于定理2累加不同周期计算得到的CRC校验值进而获得最终结果。在blue-crc的实现中,数据以大端字节序进行传输,即高位数据先传入进行处理, 假设输入数据总线位宽为256-bit, 当前周期输入数据对应的多项式为A(x), 该周期之前已经输入的数据为A'(x), 每个周期我们除了计算CRC[A(x)],还需要将该值累加到已经计算好的中间校验和CRC[A'(x)]上,得到数据

的校验和。根据定理1和2,可以推导出累加的计算公式如下:

即需要将中间校验和CRC[A'(x)]左移256-bit,对其再次计算CRC校验值后和CRC[A(x)]相加。同样我们可以通过硬件查找表的方式完成这里校验和的计算。

实际CRC的计算中原始数据的长度并不一定都是256-bit的整数倍,因此在处理最后一帧输入时不能直接使用上面的公式进行累加。我们需要动态地计算每个数据包最后一帧的有效数据的宽度,设宽度为m, 则可以采用如下公式进行累加:

03、电路架构与性能

架构设计

基于上述并行算法,CRC硬件电路的架构设计如下图所示。为了提升吞吐率,电路设计时将CRC算法需要的组合逻辑实现划分成了八级单向传递的流水线, 其中前五级流水线计算每个周期输入数据的CRC校验和并累加到CRC中间值上,后三级流水线用于处理最后一帧数据非对齐(数据位宽非总线位宽的整数倍)情况下CRC校验值的累加。每一级流水线的完成的具体功能如下:

  • Stage-1: 对AXI-Stream总线输入数据进行预处理,包括大小端转换、根据CRC配置参数reverse_input调换比特顺序、根据AXI-Stream总线tkeep字段计算数据总线上有效的字节数(用于处理数据长度非总线位宽整数倍的情况);
  • Stage-2: 对于数据长度非总线位宽整数倍的情况,需要对最后一帧数据进行移位和下一级的查找表对齐;
  • Stage-3: 从查找表中取出输入数据每个字节对应的CRC校验值;
  • Stage-4: 通过树状结构将各个字节的CRC值进行异或合并得到该周期输入数据对应的CRC校验和;
  • Stage-5: 根据上文提到的定理2,将输入数据CRC校验和累加到中间校验和之上。最后一帧输入数据(有效数据位宽可能小于总线位宽)需要特殊的处理,因此不在该流水级直接进行累加,需要将中间CRC值和上一级传来的CRC校验和传递到后续流水级进行处理;
  • Stage-6: 根据Stage-1中计算的最后一帧数据的实际有效位宽对中间CRC值进行移位和下一级的查找表对齐;
  • Stage-7: 从查找表中取出中间CRC值移位后对应的校验和;
  • Stage-8: 将上一级的查找表输出和Stage-5传递来的最后一帧输入数据的CRC校验和通过树状结构进行异或合并得到全部数据的校验和


性能与面积

CRC硬件电路的实际性能和资源开销与具体的配置参数有关。大部分情况下,硬件电路的吞吐率随输入总线数据位宽增大而提升,硬件资源开销则同时和总线宽度以及CRC校验和宽度有关。以IEEE 802-3协议规定的32位CRC校验和为例,其在256位输入总线位宽的配置下,可在Xilinx xcvu9p FPGA器件上达到500MHz的工作频率,总吞吐率达128Gb/s,实际的硬件资源开销如下。

相较于其他硬件实现方式,blue-crc主要关注于计算性能上的提升,因此在硬件资源上的开销相对较大。其中最主要的开销来源于用于实现CRC计算的查找表,其容量大小随数据总线位宽以及校验和位宽的增大而增大,具体的查找表容量的计算方式如下(设总线字节宽度为m, CRC校验和字节宽度为n):

对于上文提到的IEEE 802-3协议规定的 32-bit CRC校验,在256-bit输入总线位宽的配置下,理论上所需的查找表容量为36KB.

04、使用指南

本文的最后一部分将介绍blue-crc项目的使用指南,包括CRC电路的配置参数、输入输出接口、面向BlueSpec SystemVerilog的使用接口,以及面向Verilog的使用接口。

配置参数

在blue-crc中,CRC硬件电路完整的配置参数如下表所示:

名称含义限制
crc_widthCRC校验和的宽度目前只支持8-bit整数倍的校验和宽度
axi_keep_widthAXI-Stream总线tkeep字段宽度, 即数据字段tdata的字节宽度/
polynomialCRC生成多项式不能超过crc_width决定的取值范围
init_valueCRC初始值不能超过crc_width决定的取值范围
final_xor与输出校验和相异或的值不能超过crc_width决定的取值范围
reverse_input是否翻转每个输入字节的比特顺序两种取值: 翻转/不翻转
reverse_output是否翻转输出CRC校验值的比特顺序两种取值: 翻转/不翻转
mem_file_prefix查找表文件名前缀/
crc_modeCRC计算模式两种可选模式:(1) SEND:自动在输入原始数据尾部补零后进行除法取余, 通常用于发送端生成CRC校验和;(2)RECV:直接计算输入原始数据除法取余的结果,通常用于接收端校验;

输入输出接口

在blue-crc项目中,CRC硬件电路基于AXI-Stream总线协议接收上游模块传入的数据,校验和输出端口采用valid-ready握手机制和下游模块进行交互。电路顶层模块生成的Verilog端口如下:

module mkCrcRawAxiStreamCustom(
    input CLK,
    input RST_N,
    
    input s_axis_tvalid,
    input s_axis_tdata,
    input s_axis_tkeep,
    input s_axis_tlast,
    input s_axis_tuser,
    output s_axis_tready,
    
    output m_crc_stream_data,
    output m_crc_stream_valid,
    input  m_crc_stream_ready
);

发起CRC计算时原始数据需要按照大端字节序进行传输,即高位字节需要优先传输。假设CRC电路输入AXI-Stream总线数据位宽为32-bit (4-byte), 若要传输80-bit (10-byte)的数据,那么每一帧需要传输的内容如下图所示:

BSV使用接口

blue-crc项目基于Bluespec SystemVerilog硬件描述语言实现,因此对于使用BSV的设计者,可以直接通过实例化的方式使用CRC模块。详细的使用步骤如下:

  1. 获取blue-crc源码: blue-crc使用了blue-wrapper项目提供的AXI-Stream接口,克隆时需要加上--recursive选项获得这部分代码:
git clone --recursive https://github.com/datenlord/blue-crc.git

2. 在代码中导入所需模块:

import CrcDefines :: *;
import CrcAxiStream :: *;
import AxiStreamTypes :: *;

3. 确定CRC配置参数:CrcConfig结构体封装了电路的各项配置参数, CrcConfig结构体的定义如下, 其中每个字段的具体含义可参考前文列出的表格。其中,revInput和revOutput字段为IsReverseBitOrder枚举类型,可选取值包括BIT_ORDER_REVERSE 和 BIT_ORDER_NOT_REVERSE; crcMode字段为CrcMode枚举类型, 可选取值包括CRC_MODE_RECV和CRC_MODE_SEND。

typedef struct {
    Bit#(crcWidth) polynominal;
    Bit#(crcWidth) initVal;
    Bit#(crcWidth) finalXor;
    IsReverseBitOrder revInput;
    IsReverseBitOrder revOutput;
    String memFilePrefix;
    CrcMode crcMode;
} CrcConfig#(numeric type crcWidth) deriving(Eq, FShow);

typedef enum {
    CRC_MODE_RECV,
    CRC_MODE_SEND
} CrcMode deriving(Eq, FShow);

typedef enum {
    BIT_ORDER_REVERSE,
    BIT_ORDER_NOT_REVERSE
} IsReverseBitOrder deriving(Eq, FShow);

4. 实例化mkCrcAxiStream模块: 顶层模块接口CrcAxiStream的定义如下,数据的输入和输出分别由Get和Put接口实现

typedef Bit#(width) CrcResult#(numeric type width);
typedef Get#(CrcResult#(crcWidth)) CrcResultGet#(numeric type crcWidth);
typedef Put#(AxiStream#(keepWidth, AXIS_USER_WIDTH)) AxiStreamPut#(numeric type keepWidth);

interface CrcAxiStream#(numeric type crcWidth, numeric type axiKeepWidth);
    interface AxiStreamPut#(axiKeepWidth) crcReq;
    interface CrcResultGet#(crcWidth) crcResp;
endinterface

以IEEE 802-3协议中规定的32-bit CRC为例,若要实现输入位宽为256-bit的CRC校验值生成电路,则实例化码如下:

CrcConfig#(32) conf = CrcConfig {
    polynominal: 32'h04C11DB7,
    initVal    : 32'hFFFFFFFF,
    finalXor   : 32'hFFFFFFFF,
    revInput   : BIT_ORDER_REVERSE,
    revOutput  : BIT_ORDER_REVERSE,
    memFilePrefix: "mem_tab",
    crcMode: CRC_MODE_SEND
};
CrcAxiStream#(32, 256) crc <- mkCrcAxiStream(conf);

5. 生成查找表文件: 查找表文件的生成脚本为scripts/gen_crc_tab.py, 使用该脚本前需要先配置.json格式的CRC配置文件,该文件的内容需要和BSV代码中的配置一致:

{
    "crc_width": 32,
    "axi_keep_width": 32,
    "polynomial": "0x04C11DB7",
    "init_value": "0xFFFFFFFF",
    "final_xor": "0xFFFFFFFF",
    "reverse_input": true,
    "reverse_output": true,
    "mem_file_prefix": "crc_tab",
    "crc_mode": "CRC_MODE_SEND"
}

配置好.json文件后,使用python执行该脚本(需要传入.json配置文件路径和输出文件路径):

python3 gen_crc_tab.py JSON文件路径 文件输出路径

6. 编译项目时需要在编译选项中加入blue-crc源代码的路径, 假设blue-crc的根目录为$(ROOT), 则需要在编译选项中加上:

bsc -p +:$(BLUE_CRC)/src:$(ROOT)/lib/blue-wrapper/src


Verilog使用接口

虽然blue-crc项目基于BSV实现,但同时也提供了生成可配的Verilog代码的脚本scripts/gen_crc.py。该脚本需要在blue-crc项目的根目录下执行,同时需要传入.json格式的CRC配置文件(具体文件格式见上文):

python3 scripts/gen_crc.py JSON配置文件 [Verilog生成路径] [查找表生成路径]

若在执行脚本时没有配置Verilog代码和查找表文件生成路径,那么这些文件会默认生成到根目录下的verilog文件夹。生成Verilog代码需要使用到BSV编译器,因此在执行脚本前还需要保证已经安装并配置好该编译工具。

欢迎大家关注和支持blue-crc项目,GitHub仓库地址:https://github.com/datenlord/blue-crc

05、引用和链接

[1] Y. Sun and M. S. Kim, "A Table-Based Algorithm for Pipelined CRC Calculation," 2010 IEEE International Conference on Communications, Cape Town, South Africa, 2010, pp. 1-5, doi: 10.1109/ICC.2010.5501903.

[2] Sun Y, Kim M S. A pipelined CRC calculation using lookup tables[C]//2010 7th IEEE Consumer Communications and Networking Conference. IEEE, 2010: 1-2.

06、往期推荐

计算机体系结构 l MIT Training Q&A及小贴士

达坦科技(DatenLord)专注下一代云计算——“天空计算”的基础设施技术,致力于拓宽云计算的边界。达坦科技打造的新一代开源跨云存储平台DatenLord,通过软硬件深度融合的方式打通云间壁垒,实现数据高效跨云访问,建立海量异地、异构数据的统一存储访问机制,为云上应用提供高性能安全存储支持。以满足不同行业客户对海量数据跨云、跨数据中心高性能访问的需求。

公众号:达坦科技DatenLord

DatenLord官网:http://www.datenlord.io

知乎账号:

达坦科技DatenLord - 知乎

B站

https://space.bilibili.com/2017027518

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/808295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

#typescript 使用file-saver模块#

场景&#xff1a;前端使用file-saver模块做导出文档的时候&#xff0c;出现两个错误 1&#xff1a;npm run build 提示找不到模块&#xff0c;如图 解决方法&#xff1a; 先卸载&#xff0c;不管是否安装都先要卸载 ,然后安装&#xff1a; npm uninstall file-saver npm…

AD21原理图的高级应用(二)层次原理图设计

&#xff08;二&#xff09;层次原理图设计 1.层次原理图概述2.层次化原理图的应用2.1 自上而下的层次化原理图2.2 自下而上的层次化原理图 3.生成层次设计表 对于大规模的电路系统,需要将其按功能分解为若干个电路模块,用户可以单独绘制好各个功能模块,再将它们组合起来继续处…

DevOps-Jenkins

Jenkins Jenkins是一个可扩展的持续集成引擎&#xff0c;是一个开源软件项目&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件的持续集成变成可能。 官网 应用场景 场景一 研发人员上传开发好的代码到github代码仓库需要将代码下载nginx服务器部署手动下载再…

数据结构:快速的Redis有哪些慢操作?

redis 为什么要这莫快&#xff1f;一个就是他是基于内存的&#xff0c;另外一个就是他是他的数据结构 说到这儿&#xff0c;你肯定会说&#xff1a;“这个我知道&#xff0c;不就是 String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、 Hash&#xff08…

【雕爷学编程】MicroPython动手做(13)——掌控板之RGB三色灯2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

Spring使用注解进行对象装配(DI)

文章目录 一. 什么是对象装配二. 三种注入方式1. 属性注入2. 构造方法注入3. Setter注入 三. 三种注入方式的优缺点四. 综合练习 通过五大类注解可以更便捷的将对象存储到 Spring 中&#xff0c;同样也可以使用注解将已经储存的对象取出来&#xff0c;直接赋值到注解所在类的一…

守护进程——后台服务进程

文章目录 什么是终端进程组会话关系相关函数守护进程创建步骤应用 什么是终端 echo $$:可以查看当前进程的进程号 进程组 会话》进程组》首进程 会话 关系 >&#xff1a;重定向 |&#xff1a;管道 wc -l&#xff1a;查找 &&#xff1a;在后台去运行 SID&#xff1a;会…

小学期笔记——天天酷跑3

画笔的载体是图层 图层的载体是窗体 效果&#xff1a; ------------------- 效果&#xff1a; ---------------------- 实现一个接口可以理解成添加一个能力 接口可以理解为能力的集合 对于abstract&#xff08;判断&#xff1a;没有方法体&#xff09;&#xff0c;尽量使用…

linux系统上安装kail

1.虚拟机安装 加入kail镜像 kail系统的安装 2.更新kail的源 注释原本的源&#xff0c;加入阿里云的源 #阿里云 #deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib #deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib 参考&…

【计算机网络】11、网桥(bridge)、集线器(hub)、交换机(switch)、路由器(router)、网关(gateway)

文章目录 一、网桥&#xff08;bridge)二、集线器&#xff08;hub&#xff09;三、交换机&#xff08;switch)四、路由器&#xff08;router&#xff09;五、网关&#xff08;gateway&#xff09; 对于hub&#xff0c;一个包过来后&#xff0c;直接将包转发到其他口。 对于桥&…

【C++ 程序设计】实战:C++ 变量实践练习题

目录 01. 变量&#xff1a;定义 02. 变量&#xff1a;初始化 03. 变量&#xff1a;参数传递 04. 变量&#xff1a;格式说明符 ① 占位符 “%d” 改为格式说明符 “%llu” ② 占位符 “%d” 改为格式说明符 “%f” 或 “%e” 05. 变量&#xff1a;字节数统计 06. 变量&a…

[containerd] 在Windows上使用IDEA远程调试containerd, ctr, containerd-shim

文章目录 1. containerd安装2. 源码编译3. 验证编译的二进制文件是否含有调试需要的信息3.1. objdump工具验证3.2. file工具验证3.3. dlv工具验证 4. debug 1. containerd安装 [Ubuntu 22.04] 安装containerd 2. 源码编译 主要步骤如下&#xff1a; 1、从github下载containe…

MyBatis-Plus 查询PostgreSQL数据库jsonb类型保持原格式

文章目录 前言数据库问题背景后端返回实体对象前端 实现后端返回List<Map<String, Object>>前端 前言 在这篇文章&#xff0c;我们保存了数据库的jsonb类型&#xff1a;MyBatis-Plus 实现PostgreSQL数据库jsonb类型的保存与查询 这篇文章介绍了模糊查询json/json…

前端调用合约如何避免出现transaction fail

前言&#xff1a; 作为开发&#xff0c;你一定经历过调用合约的时候发现 gas fee 超出限制&#xff0c;但是不知道报了什么错。这个时候一般都是触发了require错误合约校验。对于用户来说他不理解为什么一笔交易会花费如此大的gas&#xff0c;那我们作为开发如何尽量避免这种情…

Power BI-网关设置与云端报表定时刷新(一)

网关的工作原理 网关是将本地数据传输至云端的桥梁&#xff0c;不仅Power BI能使用&#xff0c;其他微软软件也能够使用。 我们发布在云上的报表&#xff0c;发布后是静态的&#xff0c;不会自动刷新。需要通过网关设置定时刷新。 安装与设置 1.登录到Powerbi 在线服务–设置…

kaggle新赛:RSNA 2023 腹部创伤检测大赛赛题解析(CV)

赛题名称&#xff1a;RSNA 2023 Abdominal Trauma Detection 赛题链接&#xff1a; https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection 赛题背景 腹部钝力创伤是最常见的创伤性损伤类型之一&#xff0c;最常见的原因是机动车事故。腹部创伤可能导致…

大促之前全链路压测原理解析

1. 全链路压测的意义 上图为 2012 年淘宝核心业务应用关系的拓扑图&#xff0c;还不包含了其他的非核心业务应用&#xff0c;所谓的核心业务就是和交易相关的&#xff0c;和钱相关的业务&#xff0c;这张图大家可能看不清楚&#xff0c;看不清楚才是正常的&#xff0c;因为当时…

BGP实验

第一步&#xff1a;配置IP 第二步&#xff1a;写ospf 在R2&#xff0c;R3&#xff0c;R4&#xff0c;R5&#xff0c;R6&#xff0c;R7上分别配置ospf 如&#xff1a;R2 [R2]ospf 1 router-id 2.2.2.2 [R2-ospf-1]area 0 [R2-ospf-1-area-0.0.0.0]network 172.16.0.0 0.0.255…

wxwidgets Ribbon构建多个page与按钮响应

新建一个控制台应用程序&#xff0c;添加好头文件的依赖与lib库文件的依赖&#xff0c;修改属性&#xff1a; 将进入ribbon界面的文件与主界面的类分开&#xff1a; 1、RibbonSample.cpp #include "stdafx.h" #include "MyFrame.h" class MyApp : public…

谷粒商城第六天-商品服务之分类管理下的获取三级分类树形列表

目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端部分 2.1 在网页中建好目录及菜单 2.1.1 建好商品目录 2.1.2 建好分类管理菜单 ​编辑 2.2 编写组件 2.2.1 先完成组件文件的创建 2.2.2 编写组件 2.2.2.1 显示三级分类树形列表 三、后端部分 3.1 编写商品分类…