作风建设年活动网站/软件工程培训机构哪家好
Auto-Tuning 原理
在硬件平台驱动算子运行需要使用各种优化方式来提高性能,然而传统的手工编写算子库面临各种窘境,衍生出了自动生成高性能算子的的方式,称为自动调优。在本文我们首先分析传统算子库面临的挑战,之后介绍基于 TVM 的业界领先的三个自动调优系统。
高性能算子挑战
DNN 部署的硬件平台越来越多样化,包括 CPU、GPU、FPGA 和 ASIC,这些硬件平台内部又具有不同的资源。为了在这些平台上部署 DNN,需要对 DNN 中使用的算子使用高性能的张量程序。传统方式为使用算子库,算子库包含了大量的预定义算子(Operators),这些算子是构建和执行神经网络模型的基本单元。例如对于 CUDA 平台,使用 CuDNN 库,预先由工程师编写兼容某种 GPU 硬件平台的大量算子,在运行时直接调用。然而这种传统方式面临着越来越多的挑战:
-
优化手段的多样性:如前面的章节介绍,存在循环优化、存储优化、指令优化等多种优化方式,在编写程序时如何使用和编排这些优化是十分困难的事,不仅与硬件平台相关,也与要执行的程序相关,程序参数例如卷积核大小、特征图大小的变化也会影响优化方式的选择,再加上各种优化还涉及其优化因子如循环分块因子的选择。软硬件的组合使得编写一套高性能的算子库十分的耗费精力。
-
优化方式的通用性:程序优化方式的选择受到多种因素影响,很难有一个通用的方式能覆盖所有场景,普遍的方式是为每一种硬件的每一套参数都维护一个算子实现。以卷积算子为例,这是深度学习中最常用的算子之一。在不同的硬件上,卷积算子的实现可能会有很大差异。在 CPU 上,卷积算子可能会使用高度优化的库,如 Intel 的 MKL 或 OpenBLAS,这些库针对特定的 CPU 架构进行了优化,可以利用 SIMD 指令集等硬件特性来加速计算。在 GPU 上,卷积算子的实现通常会利用 CUDA 或 OpenCL 等并行计算框架。GPU 的高并行性使得卷积操作可以通过并行化来大幅加速。此外,不同的 GPU 架构(如英伟达的 Volta、Turing 等)可能需要不同的优化策略。
-
软硬件的快速更迭:随着新的处理器架构和专用 AI 加速器的不断涌现,硬件平台变得更加多样化。每种硬件都有其独特的特性和优化需求,算子库需要为这些不同的硬件提供定制化的算子实现,这大大增加了开发和维护的工作量。每当英伟达发布新的 CUDA 版本,引入新的 GPU 指令集时,算子库开发者必须更新 GPU 算子,以利用这些新特性来提升性能。再比如新的算子不断涌现,现在的卷积已经有几十种卷积,各种激活函数也在不断提出。每提出一个新算子,就需要在目标硬件平台实现一套算子库。
自动调优原理
为了以一种高效的方式在各种硬件平台上提供这些算子,已经引入了多种编译器技术,用户使用高层级声明性语言以类似于数学表达式的形式定义计算,编译器根据该定义生成优化的张量程序。从高层定义中自动生成高性能张量程序是非常困难的。根据目标平台的架构,编译器需要在一个非常大和复杂的空间中进行搜索,其中包含优化的组合选择(例如,分块、向量化、并行化,不同的组合导致的程序性能差异极大)。寻找高性能的程序需要搜索策略来覆盖一个全面的空间,并有效地探索它。
这一过程称为自动调优,指在编译过程中,编译器或相关工具自动调整和优化代码的执行参数,以提高程序在特定硬件上的运行效率。这通常涉及到对算法、内存访问模式、并行度等多个方面的优化。自动调优的目的是减少人工干预,使得程序能够自动适应不同的硬件环境和运行条件。在 AI 领域,这尤为重要,因为 AI 模型的计算复杂度通常很高,而且不同的硬件平台(如 CPU、GPU、FPGA 等)对计算和内存访问的优化需求各不相同。
自动调优的过程通常包括以下几个步骤:
-
性能分析:通过分析程序的运行情况,识别性能瓶颈和优化机会。
-
参数搜索:系统地探索不同的编译选项和运行参数,寻找最佳的配置。
-
性能评估:对不同的配置进行测试,评估其对性能的影响。
-
反馈学习:根据性能评估的结果,调整搜索策略,进一步优化参数选择。
自动调优可以显著提高 AI 应用的运行效率,尤其是在深度学习等计算密集型任务中。然而,由于 AI 应用的多样性和复杂性,自动调优仍然是一个活跃的研究领域,研究人员和工程师们正在不断探索更高效、更智能的调优方法。在自动调优中,TVM 是走在前列的 AI 编译器,其自动调优系统已经历经三代,本节将介绍 TVM 的这三代自动调优系统。
AutoTVM 介绍
AutoTVM 是 TVM 的第一代自动调优系统,其是基于模板的。
编写模板
AutoTVM 是基于模板的 tuner,对于每一个需要调优的算子,需要使用 TVM 的 DSL 编写调优的 knob,例如循环展开的因子、循环重排序的顺序等。例如对于矩阵乘法,可以编写这样的模板:
@autotvm.template("tutorial/matmul")
def matmul(N, L, M, dtype):A = te.placeholder((N, L), name="A", dtype=dtype)B = te.placeholder((L, M), name="B", dtype=dtype)k = te.reduce_axis((0, L), name="k")C = te.compute((N, M), lambda i, j: te.sum(A[i, k] * B[k, j], axis=k), name="C")s = te.create_schedule(C.op)# scheduley, x = s[C].op.axisk = s[C].op.reduce_axis[0]##### define space begin #####cfg = autotvm.get_config()cfg.define_split("tile_y", y, num_outputs=2)cfg.define_split("tile_x", x, num_outputs=2)##### define space end ###### schedule according to configyo, yi = cfg["tile_y"].apply(s, C, y)xo, xi = cfg["tile_x"].apply(s, C, x)s[C].reorder(yo, xo, k, yi, xi)print('original')print(tvm.lower(s,[A, B, C],simple_mode=True))return s, [A, B, C]
生成的原始调度如下:
for (i.outer: int32, 0, 512) {for (j.outer: int32, 0, 512) {C[((i.outer*512) + j.outer)] = 0f32for (k: int32, 0, 512) {let cse_var_2: int32 = (i.outer*512)let cse_var_1: int32 = (cse_var_2 + j.outer)C[cse_var_1] = (C[cse_var_1] + (A[(cse_var_2 + k)]*B[((k*512) + j.outer)]))}}}
将 i 轴和 j 轴定义为可 split 的调优轴,设置 num_outputs=2 表示单个轴会被拆分为两个轴,并且进行了循环重排序,最终循环轴会由之前的 i.outer、j.outer、k 变为 i.outer、j.outer、k、i.inner、j.inner。
例如将 i 从 512 拆分为 8 和 64,将 j 从 512 拆分为 128 和 4,生成的调度如下:
for (i.outer: int32, 0, 8) {for (j.outer: int32, 0, 128) {for (i.inner.init: int32, 0, 64) {for (j.inner.init: int32, 0, 4) {C[((((i.outer*32768) + (i.inner.init*512)) + (j.outer*4)) + j.inner.init)] = 0f32}}for (k: int32, 0, 512) {for (i.inner: int32, 0, 64) {for (j.inner: int32, 0, 4) {let cse_var_3: int32 = (j.outer*4)let cse_var_2: int32 = ((i.outer*32768) + (i.inner*512))let cse_var_1: int32 = ((cse_var_2 + cse_var_3) + j.inner)C[cse_var_1] = (C[cse_var_1] + (A[(cse_var_2 + k)]*B[(((k*512) + cse_var_3) + j.inner)]))}}}}}
该函数有多种拆分因子的选择方式,例如直接指定 candidate,给定一系列拆分方式;给定拆分时的偏好策略,是直接用乘法因子或是只要 2 的幂次方的乘法因子.
指定任务
指定待调优的算子,如 resnet18 中所有的 conv2d,TVM 会根据事先编写的 conv2d 模板生成调度搜索空间。
指定调优参数
AutoTVM 有多个 tuner,根据 index 的 random tuner 和 grid tuner、基于遗传算法的 ga tuner、基于 Xgb 的 XGBTuner。tuner 影响的是对调度搜索空间的探索,搜索空间是巨大的难以穷举的,通过 tuner 来高效搜索相对更优的调度候选项。
性能评估
对于 XGBTuner 这个具有 cost module 的 tuner,调度候选项在硬件上测量之前会使用模型预测相对性能,选出相对优的一批再去运行,这样减少真实测量的次数,减少调优时间。
关键组件
以上框架的关键组件有:
- 代码生成器:不同的调度配置会导致不同的循环结构、内存存取顺序等,生成的代码大不相同,这里使用了 TVM 的代码生成。
- 代价模型:调度搜索空间是巨大的,穷举一遍是不可能的。代价模型的作用是不断修正调度配置,选出相对最佳的配置,减少调优时间,或者说在固定的调优时间达到更好的性能。
- 硬件测量环境:AutoTVM 有 RPC tracker,可以启动多个硬件平台进行调优。
Ansor 介绍
AutoTVM 需要事先编写模板来组成调度的搜索空间,最佳性能的上限取决于模板的设计,这对模板的编写带来了很高的要求。作为第二代调优系统,Ansor(Auto Scheduler)取消了模板机制,优化过程可以自动、无干预的进行:无需手动指定优化方式,编译器自动应用调度原语。
Ansor 自动生成一个覆盖全面的优化的大搜索空间,并为空间中的每个张量程序提供被选择的机会。首先,它自动构建一个大的搜索空间,以覆盖给定计算定义的尽可能多的张量程序。其次,在大搜索空间中高效搜索,该搜索空间可能比现有模板可以覆盖的范围大几个数量级。最后,在优化具有许多子图的整个 DNN 时,识别对端到端性能至关重要的子图并对其进行优先级排序,因为资源是有限的,应该将调优时间和算力资源分配给对性能有更大影响的子图。
Ansor 有三个关键设计,分别是程序采样器、性能微调器、任务调度器。
程序采样器
为了在无模板的前提下自动生成搜索空间,递归地应用一组推导规则来扩展搜索空间;为了避免在搜索空间中陷入局部最优,使用随机抽取完整的程序给每个采样点相同概率。将搜索空间定为两级,高层结构称为草图(sketch),低级结构(分块大小、并行等)称为注解(annotation)。
递归地应用一组派生规则来生成草图,例如在 CPU 上使用这样一组规则来进行草图生成:
-
IsStrictInlinable(S,i):表示 S 中的节点是否是个简单的逐元素算子如 relu,则可以内联
-
HasDataReuse:表示节点 i 是否是计算密集型,并且有丰富的算子内部数据重用机会如 matmul、conv2d
-
HasFusibleConsumer:表示 S 中的节点 i 是否只有一个节点 j,节点 j 可以融合到节点 i(如 matmul+bias_add,conv2d+relu
-
HasMoreReducetionParallel:表示节点在空间维几乎没有并行性,但是在 reduce 维有足够的并行性。(如计算一个矩阵 l2 范数,matmul 2x512 . 512x2)
对计算的定义进行静态分析,获得这些条件谓词的值。这个过程是解析计算的数学表达式的读写模式自动完成的。与 AutoTVM 中手写模板不同,手写模板同时指定了高层规则和低层规则,而草图只有高层结构。
草图只有分块结构,没有分块大小和循环标注如并行、展开和向量化,这部分由标注完成。给定一个草图列表,随机在草图上填充分块大小、对循环进行随机标注。
性能微调器
使用进化搜索和学习成本模型来微调采样程序的性能。
- 进化搜索
在高质量程序的基础上进行突变。突变类型包括分块大小、并行、计算位置等。
- 成本模型
基于梯度增强决策树作为底层模型
任务调度器
一个 DNN 可以被划分为许多独立的子图,对于某些子图,花费时间对他们进行调优并不能显著提升整个 DNN 的端到端的性能。为了提高调优效率,Ansor 动态的将不同的时间资源进行分配。
以优化单个 DNN 的端到端延迟为例,Ansor 对具有较高初始延迟的子图进行优先排序,因为乐观猜测可以快速减少其延迟。之后,如果 Ansor 花费了多次迭代而没有观察到其延迟的减少,那么 Ansor 就会离开子图。
Ansor 也存在诸多限制,例如不能对动态形状的图进行优化,也无法使用硬件平台特定指令支持,如 Intel VNNI、NVIDIA Tensor Core。
Meta Scheduler 介绍
Meta Schedule 是第三代调优系统,在它之前,TVM 存在三套生成调度的 API:
-
手动调度:开发人员利用调度原语手动优化程序,程序性能高度依赖开发者的经验。
-
AutoTVM:开发者需要为每个算子设计一个调度生成的模板,从而使得调优器可以探索这个生成的调度空间。
-
Ansor:根据一组预定义的规则,自动生成调度模板作为设计空间。但是扩展 Ansor 到新的调度原语如张量化、流水线化等绝非易事。
上面三个系统都有独立的 API,且互不兼容。AutoTVM 要求用户学习一组新的 API,AutoScheduler 引入了另一组基于 C++ 的搜索规则。它增加了用户的心理负担和扩展现有系统的开销。
MetaSchedule 提供以下特性:
-
用于实现手动调优、AutoTVM 风格和 AutoScheduler 风格的统一 API。
-
所有调度原语的可扩展性,包括张量化和循环分块。在自动调优中使用新的原语几乎不需要额外的努力。
-
自动化基础设施在其每个组件上都是可扩展的。每个组件的系统可以在纯 python 或 C++或两者中轻松自定义。例如,可以开发一个新的在 python 中的调度空间生成器或者新的 ProgramRunner 等。
Meta Scheduler 遵循下图的调优流程:
设计空间生成
底层系统记录了用户使用的所有调度原语,以及在采样指令上做出的随机决策,称为 Trace。Trace 可能包含零条或多条采样指令,这些指令引入调度中的不确定性,形成了一个可供探索的设计空间,例如哪一组分块大小在特定硬件上效果最佳。
探索设计空间
Meta Schedule 提供了多种内置的探索策略,可以详尽或高效地进行搜索 ,来实现高效的调度。其搜索策略与之前调优器的搜索策略类似,可以随机搜索,也可以使用成本模型进行指导。
数据库
所有度量记录都经过序列化并存储在数据库中。数据库记录的内容包括工作负载,序列化的 TensorIR;执行测量的硬件目标;参数类型:输入张量的形状和 dtype;运行时间等。
在 Meta scheduler 中,成本模型、数据库、特征提取器、程序运行器等都是可定制、易于扩展的。
如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~
相关文章:

【AI系统】Auto-Tuning 原理
Auto-Tuning 原理 在硬件平台驱动算子运行需要使用各种优化方式来提高性能,然而传统的手工编写算子库面临各种窘境,衍生出了自动生成高性能算子的的方式,称为自动调优。在本文我们首先分析传统算子库面临的挑战,之后介绍基于 TVM…...

AMEYA360:上海永铭电子全新高压牛角型铝电解电容IDC3系列,助力AI服务器电源高效运转
随着数据中心和云计算的高速发展,AI服务器的能效要求日益提高。如何在有限空间内实现更高的功率密度和稳定的电源管理,成为AI服务器电源设计的一大挑战。永铭推出全新高压牛角型铝电解电容IDC3系列,以大容量、小尺寸的创新特性,为…...

echarts地图立体效果,echarts地图点击事件,echarts地图自定义自定义tooltip
一.地图立体效果 方法1:两层地图叠加 实现原理:geo数组中放入两个地图对象,通过修改zlevel属性以及top,left,right,bottom形成视觉差 配置项参考如下代码: geo: [{zlevel: 2,top: 96,map: map,itemStyle: {color: #091A51ee,opacity: 1,borderWidth: 2,borderColor: #16BAFA…...

什么是 Socket?
Socket(套接字)是计算机网络编程中的一个重要概念,它用于在不同计算机之间进行通信。Socket 提供了一种机制,使得应用程序可以通过网络发送和接收数据。Socket 通信通常基于 TCP/IP 协议,但也可以使用其他协议…...

【版本控制】SVN安装到使用一条路讲解
文章目录 安装使用 Subversion (SVN) 是一款集中式版本控制系统,广泛应用于团队协作和代码管理中。尽管随着 Git 的兴起,集中式版本控制逐渐被分布式工具取代,但 SVN 仍在许多企业项目中发挥着重要作用。它的简单、稳定和易用特性,…...

KVCKVO
KVC KVC意思是键值编码,是一种可以通过键名来访问对象属性的机制,也可以对属性进行赋值,包括私有属性,由于KVC的定义是对OC中的NSObject的扩展进行实现的,所以如果要使用KVC机制,那么这个类需要继承NSObje…...

PyQt设计界面优化 #qss #ui设计 #QMainWindow
思维导图 通过qss实现ui界面设计优化 Qss是Qt程序界面中用来设置控件的背景图片、大小、字体颜色、字体类型、按钮状态变化等属性,它是用来美化UI界面。实现界面和程序的分离,快速切换界面。 首先我们在Pytchram创建一个新目录 然后将我们所需要的图片打…...

Qt Serial Bus 前置介绍篇
文章目录 Qt Serial Bus 简介前言 什么是 Qt Serial Bus?Qt Serial Bus 的核心功能支持的协议1. **CAN 总线**2. **Modbus**3. **自定义协议** 应用场景优势总结 Qt Serial Bus 简介 前言 Qt Serial Bus 是 Qt 框架中的一个模块,用于与工业设备和嵌入式…...

12.2深度学习_项目实战
十、项目实战 鲍勃开了自己的手机公司。他想与苹果、三星等大公司展开硬仗。 他不知道如何估算自己公司生产的手机的价格。在这个竞争激烈的手机市场,你不能简单地假设事情。为了解决这个问题,他收集了各个公司的手机销售数据。 鲍勃想找出手机的特性(例…...

LeetCode 64. 最小路径和(HOT100)
第一次错误代码: class Solution { public:int minPathSum(vector<vector<int>>& grid) {int dp[205][205] {0};int m grid.size(),n grid[0].size();for(int i 1 ;i<m;i){for(int j 1;j<n;j){dp[i][j] min(dp[i][j-1],dp[i-1][j])gr…...

ESP8266作为TCP客户端或者服务器使用
ESP8266模块,STA模式(与手机搭建TCP通讯,EPS8266为服务端)_esp8266作为station-CSDN博客 ESP8266模块,STA模式(与电脑搭建TCP通讯,ESP8266 为客户端)_esp8266 sta 连接tcp-CSDN博客…...

C#结合.NET框架快速构建和部署AI应用
在人工智能(AI)的浪潮中,C#作为一种功能强大且类型安全的编程语言,为AI工程开发提供了坚实的基础。C#结合.NET框架,使得开发者能够快速构建和部署AI应用。本文将通过一个简单的实例,展示如何使用C#进行AI工…...

题外话 (火影密令)
哥们! 玩火影不! 村里人全部评论! 不评论的忍战李全保底! 哥们! 密令领了不! “1219村里人集合”领了吗! 100金币! 哥们! 我粉丝没人能上影! 老舅说的…...

蓝桥杯准备训练(lesson1,c++方向)
前言 报名参加了蓝桥杯(c)方向的宝子们,今天我将与大家一起努力参赛,后序会与大家分享我的学习情况,我将从最基础的内容开始学习,带大家打好基础,在每节课后都会有练习题,刚开始的练…...

RTDETR融合[ECCV2024]WTConvNeXt中的WTConv模块及相关改进思路
RT-DETR使用教程: RT-DETR使用教程 RT-DETR改进汇总贴:RT-DETR更新汇总贴 《Wavelet Convolutions for Large Receptive Fields》 一、 模块介绍 论文链接:https://arxiv.org/pdf/2407.05848 代码链接:https://github.com/BGU-CS…...

AD7606使用方法
AD7606是一款8通道最高16位200ksps的AD采样芯片。5V单模拟电源供电,真双极性模拟输入可以选择10 V,5 V两种量程。支持串口与并口两种读取方式。 硬件连接方式: 配置引脚 引脚功能 详细说明 OS2 OS1 OS2 过采样率配置 000 1倍过采样率 …...

嵌入式系统应用-LVGL的应用-平衡球游戏 part1
平衡球游戏 part1 1 平衡球游戏的界面设计2 界面设计2.1 背景设计2.2 球的设计2.3 移动球的坐标2.4 用鼠标移动这个球2.5 增加边框规则2.6 效果图2.7 游戏失败重启游戏 3 为小球增加增加动画效果3.1 增加移动效果代码3.2 具体效果图片 平衡球游戏 part2 第二部分文章在这里 1 …...

JVM(四) - JVM 内存结构
目录 一、程序计数器 1.1 作用 1.2 概述 二、虚拟机栈 2.1 概述 2.2 栈的存储单位 2.3 栈运行原理 2.4 栈帧的内部结构 2.4.1. 局部变量表 槽 Slot 2.4.2. 操作数栈 概述 栈顶缓存(Top-of-stack-Cashing) 2.4.3. 动态链接(指向…...

【AI系统】CANN 算子类型
CANN 算子类型 算子是编程和数学中的重要概念,它们是用于执行特定操作的符号或函数,以便处理输入值并生成输出值。本文将会介绍 CANN 算子类型及其在 AI 编程和神经网络中的应用,以及华为 CANN 算子在 AI CPU 的详细架构和开发要求。 算子基…...

VUE脚手架练习
脚手架安装的问题: 1.安装node.js,配置环境变量,cmd输入node -v和npm -v可以看到版本号(如果显示不是命令,确认环境变量是否配置成功,记得配置环境变量之后重新打开cmd,再去验证) 2.在安装cnmp时…...

动态艺术:用Python将文字融入GIF动画
文章内容: 在数字媒体的多样化发展中,GIF动画作为一种流行的表达形式,常被用于广告、社交媒体和娱乐。本文通过一个具体的Python编程示例,展示了如何将文字以动态形式融入到GIF动画中,创造出具有视觉冲击力的动态艺术…...

更多开源创新 挑战OpenAI-o1的模型出现和AI个体模拟突破
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

VR眼镜可视化编程:开启医疗信息系统新纪元
一、引言 随着科技的飞速发展,VR 可视化编程在医疗信息系统中的应用正逐渐成为医疗领域的新趋势。它不仅为医疗教育、手术培训、疼痛管理等方面带来了新的机遇,还在提升患者体验、推动医疗信息系统智能化等方面发挥着重要作用。 在当今医疗领域…...

Ubuntu访问简书403
日期 二〇二四年十二月三日 操作系统 Ubuntu 22.04 浏览器 firefox 问题 打开简书提示403. 原因 简书不认带ubuntu的UA 解决办法 - 浏览器地址栏输入 about:config。接受风险 - 搜索 general.useragent.override,无则新建 string类型。 - 查看浏览器 UA&…...

SQL高级应用——索引与视图
数据库优化离不开索引和视图的合理使用。索引用于加速查询性能,而视图则在逻辑层简化了查询逻辑,提高了可维护性。本文将从以下几个方面详细探讨索引与视图的概念、应用场景、优化技巧以及最新的技术发展: 1. 索引类型与应用场景 索引是数据…...

docker部署文件编写(还未尝试)
docker文件启动mysql 要使用Docker启动MySQL,您可以通过以下步骤编写Dockerfile: 选择一个基础镜像,通常是一个包含了MySQL的Linux发行版。 设置环境变量,如MySQL的root密码等。 在容器启动时运行MySQL服务。 以下是一个简单…...

缓存与数据库数据一致性 详解
缓存与数据库数据一致性详解 在分布式系统中,缓存(如 Redis、Memcached)与数据库(如 MySQL、PostgreSQL)一起使用是提高系统性能的常用方法。然而,缓存与数据库可能因更新时序、操作失误等原因出现数据不一…...

每日计划-1203
1. 完成 236. 二叉树的最近公共祖先 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution {public:TreeNode* lowe…...

HTML5动漫主题网站——天空之城 10页 html+css+设计报告成品项目模版
📂文章目录 一、📔网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站演示 五、⚙️网站代码 🧱HTML结构代码 💒CSS样式代码 六、🔧完整源码下载 七、📣更多 一、&#…...

分布式会话 详解
分布式会话详解 在分布式系统中,用户的会话状态需要在多个服务器或节点之间共享或存储。分布式会话指的是在这种场景下如何管理和存储会话,以便在多个节点上都能正确识别用户状态,从而保证用户体验的一致性。 1. 为什么需要分布式会话 在单…...