2022年全国研究生数学建模竞赛华为杯D题PISA架构芯片资源排布问题求解全过程文档及程序

2022年全国研究生数学建模竞赛华为杯

D题 PISA架构芯片资源排布问题

原题再现:

  一、背景介绍
芯片是电子行业的基础,在当前日益复杂的国际形势下,芯片成了各个大国必争的高科技技术。本课题关注网络通信领域的交换芯片,传统的交换芯片功能固定,当出现新的网络协议时,必须重新设计芯片,而芯片从设计到使用,往往需要几年的时间,因此固定功能的交换芯片大大降低了研发效率,为了解决此问题,诞生了可编程的交换芯片。PISA(Protocol Independent Switch Architecture)是当前主流的可编程交换芯片架构之一,其有着和固定功能交换芯片相当的处理速率,同时兼具了可编程性,在未来网络中具有广阔的应用场景[1-2]。
在对PISA架构作进一步说明之前我们首先澄清几个基本概念:
  1. 报文:报文即网络通信中传输的数据包,在网络通信中,用户传输的数据被封装成一个个的数据包进行传输。
  2. 基本块:基本块是源程序的一个程序片段,对源程序进行基本块划分会将源程序划分为一个个的基本块。至于基本块如何划分本身也是一个值得探讨的问题,但超出了本问题的范围,在此不再多加赘述。
  3. 流水线:流水线为一系列处理单元串联构成,报文在流水线中按次序依次通过每个处理单元,最终完成处理。流水线各级即是指流水线中各处理单元。
  PISA架构如图1所示,其包括报文解析(parser)、多级的报文处理流水线(Pipeline Pocket Process)、以及报文重组(Deparser)三个组成部分。报文解析用于识别报文种类;多级的报文处理流水线用于修改报文数据,在实际的PISA架构芯片中,不同的芯片流水线的级数可能不同;报文重组用于报文重新组装。本课题只关注其中多级的报文处理流水线部分。在PISA架构编程模型中,用户使用P4语言描述报文处理行为得到P4程序,再由编译器编译P4程序,进而生成芯片上可以执行的机器码。编译器在编译P4程序时,会首先将P4程序划分为一系列的基本块,再将各基本块排布到流水线各级当中。由于各基本块均会占用一定的芯片资源,将基本块排布到流水线各级即是将各基本块的资源排布到流水线各级当中(即需要确定每个基本块排布到流水线哪一级),因此我们将基本块的排布问题称作PISA架构芯片资源排布问题。在实际的PISA架构芯片的设计中,为了减少连线的复杂度,往往对流水线各级的资源、以及流水线各级之间的资源有着多种多样的约束条件,这一系列复杂的资源约束条件使得资源排布问题尤为困难。然而,芯片的各类资源均有限,越高的资源利用率意味着能够越好的发挥芯片的能力,让芯片支持更多的业务,因此,高资源利用率的资源排布算法对于编译器设计至关重要。
在这里插入图片描述

图1 PISA架构图
   二、问题描述 由基本块定义可知基本块为源程序的片段,基本块中会执行指令来完成计算,指令执行时会读取指令源操作数(即读源操作数对应的变量)进行计算,再将计算结果赋值给目的操作数(即写目的操作数对应的变量)。对于划分好的基本块,每个基本块中的指令并行执行,执行时按照先读后写的顺序(由芯片底层实现所决定),即先同时读出所有的目的操作数,再并行执行所有指令的计算,最后同时将计算结果赋值给目的操作数。由于并行向同一个变量写多次时存在冲突,因此每个基本块只会写同一个变量一次(即基本块中不存在多条指令对相同变量赋值)。   基本块可以被抽象成一个节点,抽象后基本块中执行的具体指令被屏蔽,只保留读写的变量信息。当基本块A执行完可以跳转到基本块B执行时,在A和B之间增加一条有向边,这样P4程序即可表示为一个有向无环图(P4程序不存在循环),称作P4程序流程图,如图2左图所示。PISA架构资源排布即是将P4程序流程图中的各节点(即各基本块)在满足约束条件下排布到流水线各级当中。约束条件来自于两方面,一方面来自于P4程序本身,P4程序每个基本块均会写一部分变量(即对变量赋值)和读一部分变量,变量的读写使得基本块之间存在数据依赖,同时,基本块执行完后可能跳转到多个基本块执行,从而使得基本块之间也存在着控制依赖,数据依赖和控制依赖约束了基本块排布的流水线级数的大小关系,关于数据依赖和控制依赖的详细说明参见附录A;另一方面的约束条件来自于芯片的资源约束,芯片中的资源包括TCAM、HASH、ALU、QUALIFY四类(附录B中解释了四类资源的作用以供感兴趣的同学进一步了解,不了解并不影响问题作答)。流水线中针对于这四类资源有着严格的限制(具体的资源限制在赛题中进行说明),资源排布时不能违反芯片的资源限制。   本问题中,输入数据给出了各基本块在P4程序流程图中的邻接关系,各基本块占用的四类资源的数量,以及各基本块读写的变量信息,本问题的赛题总共包括两个子问题,需要同学们在满足上述数据依赖、控制依赖、以及各具体子问题的资源约束条件下进行资源排布,并充分考虑各子问题的优化目标,以求最大化芯片资源利用率。   为了帮助大家进一步理解本问题,在附录C中给出了一个简单的资源排布示例。

在这里插入图片描述

图2 PISA架构资源排布示意图

  三、输入数据说明
  输入数据包含三个附件,分别给出了各基本块资源使用情况、各基本块读写的变量信息、以及各基本块在流图中的邻接基本块,各附件格式如下:
  (1)attachment1.csv:各基本块使用的资源信息
在这里插入图片描述
  表中第一列为基本块编号,第2列到第5列为各基本块使用的四种资源的数目,资源总共分为四种(TCAM、HASH、ALU、QUALIFY),比如由上表可以知道,0号基本块需要占用2个ALU资源,4号基本块需要占用10个ALU资源和3个Qualify资源。
  (2)attachment2.csv:各基本块读写的变量信息
在这里插入图片描述
  表中第一列表示基本块编号,第二列中“W”表示写,“R”表示读,后续列表示本基本块写或者读的变量,当某一行从第三列及后续列没有任何元素时,说明此编号的基本块没有写(或读)任何变量(此时该基本块单纯作为连接其它基本块的中间基本块,没有执行任何计算)。例如:0号基本块写了变量X0、X1,但没有读任何变量,1号基本块既没有写任何变量,也没有读任何变量。
  (3)attachment3.csv:各基本块在流程图中的邻接基本块信息
在这里插入图片描述
  表中第一列为基本块编号,后续列为与当前基本块在流程图中邻接的基本块编号,即在流程图(如图2左图所示)中,本基本块到后续列中的基本块之间存在有向边连接。比如,由上表第一行可知,0号基本块到1号基本块和2号基本块之间存在有向边连接(即0号基本块执行结束后可以跳转到1号基本块或2号基本块执行),由第三行可知从2号基本块出发没有边(即基本块2执行后程序结束,不会再跳转到其它基本块执行)。通过此文件可以确定基本块在源程序的执行顺序,确定每个基本块执行后跳转的目的基本块,进而构建起基本块的流程图。

  四、问题
  本课题需要建立资源排布问题的数学模型,并在此基础上处理如下两个问题。
  问题1:给定资源约束条件如下:
  (1)流水线每级的TCAM资源最大为1;
  (2)流水线每级的HASH资源最大为2;
  (3)流水线每级的ALU资源最大为56;
  (4)流水线每级的QUALIFY资源最大为64;
  (5)约定流水线第0级与第16级,第1级与第17级,…,第15级与第31级为折叠级数,折叠的两级TCAM资源加起来最大为1,HASH资源加起来最大为3。注:如果需要的流水线级数超过32级,则从第32开始的级数不考虑折叠资源限制;
  (6)有TCAM资源的偶数级数量不超过5;
  (7)每个基本块只能排布到一级。
  在上述资源约束条件下进行资源排布,并以占用的流水线级数尽量短为优化目标。请给出资源排布算法,输出基本块排布结果,输出的结果格式如下:

在这里插入图片描述
  问题2:考虑如图3所示的流图,基本块2和基本块3不在一条执行流程上(因为基本块1执行完后要么执行基本块2,要么执行基本块3,基本块2和基本块3不可能都执行)。准确来说,在P4程序流程图中,由一个基本块出发可以到达另一个基本块则两基本块在一条执行流程上,反之不在一条执行流程上。对于这种不在一条执行流程上的基本块,可以共享HASH资源和ALU资源,基本块2和3中任意一个的HASH资源与ALU资源均不超过每级资源限制,基本块2和3即可排布到同一级。据此,对问题1中的约束条件(2)、(3)、(5)作如下更改:
  (2)流水线每级中同一条执行流程上的基本块的HASH资源之和最大为2;
  (3)流水线每级中同一条执行流程上的基本块的ALU资源之和最大为56;
  (5)折叠的两级,对于TCAM资源约束不变,对于HASH资源,每级分别计算同一条执行流程上的基本块占用的HASH资源,再将两级的计算结果相加,结果不超过3。
  其它约束条件同问题1,更改资源约束条件后重新考虑问题1,给出排布算法,输出基本块排布结果。输出格式同问题1。
在这里插入图片描述

图3 流图示例

整体求解过程概述(摘要)

  随着全球“芯”缺浪潮的持续发酵,作为“工业粮食”的芯片技术成为我国亟待突围的产业之一。PISA 作为兼具良好处理速度与可编程性的交换芯片架构,有效缓解了传统固定功能的交换芯片研发效率低下的问题。为充分发挥芯片能力,高资源利用率的芯片资源排布算法的选择显得尤其重要。鉴于此,本文将复杂的基本块资源排布问题拆解为多个子问题,并结合各类约束条件,通过建立目标规划模型与基本块排布模型逐步求解,然后设计启发式规则对求解结果进行优化,最终将得到的尽可能短的流水线级数作为问题的解。
  针对问题一,本文将其划分为依赖关系分析和基本块资源排布两个子问题。针对子问题一,分析处理附件 attachment3.csv 数据得到控制流图 CFG 与控制流图的前向支配树FDT,CFG 和 FDT 差集即为基本块的控制依赖关系。其次,读取附件 attachment2.csv 中基本块的读写关系,利用广度优先搜索算法 BFS 判断基本块间的连通性来确定数据依赖关系。将控制依赖与数据依赖关系取并集得到完整的依赖关系。针对子问题二,将完成的依赖关系抽象为带权有向无环图,初步确定基本块在流水线中排布的层级关系。然后,以占用尽量短的流水线级数为主要目标,结合 attachment1.csv 中的基本块资源需求和给定的资源约束条件建立了目标规划模型。模型的求解设计了基本块排布模型,依据串行排布的原则,从无前序依赖关系的基本块中依据随机规则选取基本块放入最早可放入的流水线级,直到所有基本块完成排布。问题一得出流水线占用级数为 40 级。
  针对问题二,由于不在一条执行流程上的基本块可以共享 HASH 资源和 ALU 资源,我们在问题一的基础上引入不在一条执行流程上的基本块的概念,缓解了问题一中对HASH 和 ALU 的占用问题。本文将问题二拆解为判断两个基本块是否在同一条执行流程、基本块资源排布两个子问题。针对子问题一,根据程序流程图,利用广度优先搜索算法判断两个基本块是否在一条执行流程上,即从一个基本块出发是否可到达另一个基本块,获得基本块执行流程关系对称矩阵。针对问题二,同样以占用尽量短的流水线级数为主要目标,结合不在同一执行流程上的基本块可共享 HASH 和 ALU 资源这一条件与更改后的三个约束,建立与问题一类似的目标规划模型。求解时对于有新的基本块排布的流水线,合并该级流水线中与其处于不同控制流的基本块对 HASH 和 ALU 的资源需求。问题二得出流水线占用的级数为 34 级。
  求解方案优化考虑到随机规则选取的不稳定性,对基本块选取规则进行优化,本文构建了最早开始时间 EST、最多紧后资源块 MST、最早开始时间且最多紧后资源块EST_MST 等 6 种启发式规则,依据启发式规则选取要加入流水线的基本块。本文综合了10 次随机规则和 6 种启发式规则求解的最优结果作为最终的流水线排布方案。优化后,问题一得出流水线占用级数为 40 级。问题二得出流水线占用的级数为 34 级。最后,本文发现了问题一的性能瓶颈在于 HASH 资源,问题二的性能瓶颈在于TCAM 资源。通过综合考虑控制依赖、数据依赖和各级流水线的资源约束条件,证明了所提方案的有效性与普适性。总结了所提算法与模型的优缺点,并对未来研究工作进行了展望。

模型假设:

  [1] 假设实验场景均位于理想状态,不受温度和电磁等因素影响。
  [2] 假设实验过程中不存在由芯片故障导致的误差。
  [3] 假设只关注 PISA 架构芯片多级的报文处理流水线部分。
  [4] 假设每级流水线除题目所给的资源约束外,其他条件均相同。
  [5] 假设可排布的流水线级数没有上限。
  [6] 假设随机模型种取随机数的过程是完全随机的。

问题分析:

问题一分析:

  问题一要求考虑各基本块间的数据依赖、控制依赖关系情况下,结合给定的资源约束条件,实现基本块资源排布并优化,使占用的流水线级数尽量短,以求最大化芯片资源利用率。题目给出 attachment1.csv、attachment2.csv、attachment3.csv 三个附件分别为各基本块使用的资源信息、各基本块读写的变量信息以及各基本块在流程图种的邻接基本
块信息。
  通过对题目分析,我们得出本题可拆解为以下三个子问题:
  子问题一:通过设计算法与模型,对附件二、附件三中的数据进行处理分析,确定各基本块间的控制依赖关系与数据依赖关系,从而初步确定基本块在流水线中排布的层级关系。
  子问题二:结合题目所给资源约束条件与附件一的资源使用数据,建立模型,确定基本块在流水线中的级数排布情况。
  子问题三:对基本块排布进行优化,使得基本块占用的流水线级数尽可能短。

问题二分析:

  问题二在问题一的基础上引入不在一条执行流程上的基本块的概念,对于不在一条执行流程上的基本块,可以共享 HASH 资源和 ALU 资源。由此,问题二对于问题一缓解了 HASH 和 ALU 的占用。问题同样要求给出基本块在流水线中的排布算法与结果,但对约束条件进行了更改。
  结合分析,问题二可拆解为以下两个子问题:
  子问题一:根据程序流程图,建立模型,确定一个基本块出发是否可到达另一个基本块,即两个基本块是否在一条执行流程上。
  子问题二:结合不在同一执行流程上的基本块可共享 HASH 和 ALU 资源这一条件与更改后的约束,建立模型,确定基本块在流水线中的级数排布情况,并使占用的流水线级数尽量短。

模型的建立与求解整体论文缩略图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

程序代码:

部分Python程序如下:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import csv
import scipy as sp
# 入度
inGF = []
# 第一步:dfs
dfn = []
rak = []
fa = []
search_path = []
# 第二步:sdom
val = []
bel = []
sdom = []
# 第三步:idom
idom = []
# 比较获取 CDG
cdg = []
idomGF = nx.DiGraph()
def read_csv3(file_name):
f = open(file_name, encoding='UTF8')
csv_reader = csv.reader(f)
control_edges = []
for line in csv_reader:
adj_num = len(line)
if adj_num > 1:
for i in range(1, adj_num):
control_edges.append((int(line[0]), int(line[i])))
f.close()
# print(control_edges)
return control_edges
def subgraph(pointList, linkList):
G = nx.DiGraph()
GF = nx.DiGraph()
# 转化为图结构
for node in pointList:
G.add_node(node)
GF.add_node(node)
for link in linkList:
G.add_edge(link[0], link[1])
GF.add_edge(link[1], link[0])
return G, GF
def dfs(GF):
# GF 的 root 为人为添加的序号最大的根
root = len(GF.nodes) - 1
T = nx.dfs_tree(GF, root)
for n in GF.nodes():
fa.append(0)
dfn.append(n)
global rak
rak = list(T) # 所有节点
for i in range(0, len(fa)):
dfn[rak[i]] = i
for i in list(T.edges): # 所有边
fa[i[1]] = i[0]
# print(dfn)
# print(rak)
# print(fa)
def find(v):
# 还未被遍历
if v == bel[v]:
return v
tmp = find(bel[v])
if (dfn[sdom[val[bel[v]]]] < dfn[sdom[val[v]]]):
val[v] = val[bel[v]]
bel[v] = tmp
return bel[v]
def tarjanFDT():
# 初始化 val 和 sdom
for i in range(0, len(dfn)):
val.append(i)
sdom.append(i)
bel.append(i)
idom.append(i)
# 从大到小遍历 dfs 树
for i in range(len(dfn) - 1, 0, -1):
# dfs 序最大的点 u
u = rak[i]
# 获取 GF 原图中所有 u 的前驱
neighbors = G.neighbors(u)
for v in neighbors:
find(v)
if (dfn[sdom[val[v]]] < dfn[sdom[u]]):
sdom[u] = sdom[val[v]]
# print(sdom)
sdomGF = nx.DiGraph()
for i in range(0, len(sdom)):
sdomGF.add_node(i)
sdomGF.add_edge(sdom[i], i)
bel[u] = fa[u]
u = fa[u]
neighbors = sdomGF.neighbors(u)
for v in neighbors:
find(v)
if sdom[val[v]] == u:
idom[v] = u
else:
idom[v] = val[v]
for i in range(0, len(dfn)):
u = rak[i]
if idom[u] != sdom[u]:
idom[u] = idom[idom[u]]
global idomGF
for i in range(0, len(idom)):
idomGF.add_node(i)
idomGF.add_edge(idom[i], i)
# nx.draw_networkx(sdomGF, with_labels=True)
# plt.show()
# nx.draw_networkx(idomGF, with_labels=True)
# plt.show()
def getInGF():
# 遍历 GF 所有点
for i in range(0, len(GF.nodes)):
# 初始化:0 标识入度为 0
inGF.append(0)
for edge in GF.edges:
inGF[edge[1]] = 1
def addGFRoot():
# print(len(GF.nodes))
GF.add_node(len(GF.nodes))
for i in range(0, len(inGF)):
if inGF[i] == 0:
GF.add_edge(len(GF.nodes) - 1, i# nx.draw_networkx(GF, with_labels=True)
# plt.show()
if __name__ == '__main__':
# 读 attachment3.cvs
linkList = read_csv3("./data/attachment3.csv")
pointList = []
for i in range(0, 607):
pointList.append(i)
# 原始有向无环图 G,反向图 GF
G, GF = subgraph(pointList, linkList)
# 获取 GF 入度为 0 的所有点
getInGF()
# 为 GF 添加根节点
addGFRoot()
# 获取 G 的前向支配树,也就是 GF 的支配树,存储在 idomGF 中(即
FDT)
dfs(GF)
tarjanFDT()
# 对比 G 原图和 FDT 图,寻找在 G 但不在 FDT 中的边,得到 CDG
for edgeG in G.edges:
edgeGf = (edgeG[1], edgeG[0])
# 标识是都存在相同,初始化为 0
flag = 0
for edgefdt in idomGF.edges:
if edgeGf == edgefdt:
flag = 1
break
else:
continue
if flag == 0:
cdg.append(edgeG)
f = open("./data/control_dependance_less_equal.txt", "w")
f.writelines(str(cdg))
f.close()
print(len(cdg))
print(cdg)
全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫逆向猿人学刷题系列——第七题

题目&#xff1a;采集这5页中胜点列的数据&#xff0c;找出胜点最高的召唤师&#xff0c;将召唤师姓名填入答案中 地址&#xff1a;https://match.yuanrenxue.cn/match/7 本题主要是考察字体的动态变化&#xff0c;同样也是从字体文件下手构造出映射关系就好&#xff0c;但本题…

TuyaOS开发学习笔记(2)——NB-IoT开发SDK架构、运行流程

一、SDK架构 1.1 架构框图 基于 TuyaOS 系统&#xff0c;可以裁剪得到的适用于 NB-IoT 协议产品接入的 SDK。SDK 将设备配网、上下行数据通信、产测授权、固件 OTA 升级等接口进行封装&#xff0c;并提供相关函数。 1.2 目录结构 1.2.1 TuyaOS目录说明 adapter&#xff1a;T…

70、Spring Data JPA 的 自定义查询(全手动,自己写完整 SQL 语句)

1、方法名关键字查询&#xff08;全自动&#xff0c;既不需要提供sql语句&#xff0c;也不需要提供方法体&#xff09; 2、Query查询&#xff08;半自动&#xff1a;提供 SQL 或 JPQL 查询&#xff09; 3、自定义查询&#xff08;全手动&#xff09; ★ 自定义查询&#xff08…

范文展示,如何三步写出一篇满意的论文

第一步&#xff1a;输入文章关键信息 文章标题&#xff0c;写论文的话即为拟定的论文标题&#xff0c;例如这篇范文中的题目为“阳明心学研究” 关键词&#xff0c;可以写出多个论文主题相关的关键词&#xff0c;用逗号分开&#xff0c;例如这篇范文中只写了一个关键词“王阳…

9.12 C++作业

实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xff1a;半…

长城网络靶场第三题

关卡描述&#xff1a;1.oa服务器的内网ip是多少&#xff1f; 先进行ip统计&#xff0c;开始逐渐查看前面几个ip 基本上都是b/s&#xff0c;所以大概率是http&#xff0c;过滤一下ip 第一个ip好像和oa没啥关系 第二个ip一点开就是 oa&#xff0c;应该就是他了。 关卡描述&a…

指针-子串逆置

任务描述 从标准输入上读入以空格分隔的字符串 s 和 t&#xff0c;将 s 中与 t 匹配的所有子串逆置后再输出 s&#xff0c;当 s 中无与 t 匹配的子串时直接输出字符串 s。已经匹配的字符不会再重复匹配。 相关知识 参考之前的关卡。 编程要求 根据提示&#xff0c;在右侧编…

Golang编写自定义IP限流中间件

目录 基于令牌桶的限流算法实现高并发限流&#xff08;使用golang官方限流器&#xff09;Go代码测试记录ab -t 1 -c 1 http://127.0.0.1:8080/api/resource结果预测&#xff1a;1秒内最多生成10个令牌&#xff0c;而总共有20个串行的请求&#xff0c;结果应该是1个成功&#xf…

CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0

https://downloads.mysql.com/archives/community/是社区版的官网&#xff0c;可以选择版本下载。 cat /etc/redhat-release可以看到系统版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到版本是3.10.0-957.el7.x86_64。 yum remove -y mysql-libs把…

来看看Python MetaClass元类详解

MetaClass元类&#xff0c;本质也是一个类&#xff0c;但和普通类的用法不同&#xff0c;它可以对类内部的定义&#xff08;包括类属性和类方法&#xff09;进行动态的修改。可以这么说&#xff0c;使用元类的主要目的就是为了实现在创建类时&#xff0c;能够动态地改变类中定义…

Python3.10 IDLE更换主题

前言 自定义主题网上有很多&#xff0c;3.10IDLE的UI有一些新的东西&#xff0c;直接扣过来会有些地方覆盖不到&#xff0c;需要自己测试着添几行配置&#xff0c;以下做个记录。 配置文件路径 Python安装目录下的Lib\idlelib\config-highlight.def。如果是默认安装&#xf…

轻松鲨-AI文案写作 人工智能聊天

轻松鲨AI助手使用地址&#xff1a;http://www.qingsongsha.com?utm_sourcenavigation_website 或前往苹果App Store下载“轻松鲨APP” 支持AI连续对话聊天&#xff0c;帮你解答各种疑问... 让AI帮你画思维导图写文案&#xff0c;提升工作效率... 内置多场景专业模板&#xff0…

解决 tesserocr报错 Failed to init API, possibly an invalid tessdata path : ./

问题描述 我们在初次使用tesserocr库的时候&#xff0c;可能会报以下错误&#xff1a; RuntimeError: Failed to init API, possibly an invalid tessdata path: ./ 这是因为我们在使用 conda 创建的环境中找不到"tessdata"这个文件夹。 解决办法 这时候把Tessera…

品牌是什么?品牌加分秘笈曝光

作为一个多年的品牌人&#xff0c;这几年&#xff0c;历经迷惘和探索&#xff0c;迷惘在于&#xff1a; 1.品牌部是花钱部门&#xff0c;不直接创造营收&#xff0c;不受老板重视、钱少。 2.品牌作业难以衡量&#xff0c;一般以曝光、阅读、声量指数等指标来衡量&#xff0c;…

026-从零搭建微服务-文件服务(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

鼠标拖拽拖动盒子时,与盒子内某些点击事件冲突问题解决

目录 问题解决思路解决代码&#xff08;标注【主要代码】的为重点&#xff09; 问题 拖动该悬浮球时&#xff0c;鼠标弹起可能会触发悬浮球内事件 解决思路 鼠标拖动盒子时&#xff0c;将 isMove 设为 true 意为正在拖动盒子&#xff0c;此时将 class"btns_move" 遮…

利用 SOAR 加快事件响应并加强网络安全

随着攻击面的扩大和攻击变得越来越复杂&#xff0c;与网络攻击者的斗争重担落在了安全运营中心 &#xff08;SOC&#xff09; 身上。SOC 可以通过利用安全编排、自动化和响应 &#xff08;SOAR&#xff09; 平台来加强组织的安全态势。这一系列兼容的以安全为中心的软件可加快事…

单元格法近似求解多边形最大内接矩形问题【思路讲解+java实现】

文章目录 问题描述问题解决方案多边形网格化区分每个单元格是在多边形内部还是外部根据已标记单元格寻找最大内接矩形剪枝优化多角度旋转 案例测试代码实现说明 问题描述 给定一个多边形的点集&#xff0c;希望找出多边形内部面积最大的矩形。该问题可能出现在&#xff0c;从一…

聊聊Spring事务同步器TransactionSynchronization

在一些业务场景中可能我们需要去对某一个spring事务的生命周期进行监控&#xff0c;比如在这个事务提交&#xff0c;回滚&#xff0c;被挂起的时候&#xff0c;我们想要去执行一些自定义的操作&#xff0c;这怎么去做呢&#xff1f;其实spring作为一个高扩展性的框架&#xff0…

关系型三大范式与BCNF有什么用呢

学的时候就知道是一堆公式。 实际中在设计表的时候可能会用到。 前提是关系型数据库&#xff0c;比如mysql。 &#xff08;实际中oracle比mysql更好用。但是他收费啊。&#xff09; 第一范式&#xff1a;每个属性都是原子的&#xff08;需要做到每个属性都是不可分割的。&…