roofline model加速模型部署最后一公里

文章目录

  • 模型部署教程来啦:)
    • 什么是Roofline Model?
      • 算法模型相关指标
        • 计算量
        • 计算峰值
        • 参数量
        • 访存量
        • 带宽
        • 计算密度
          • kernel size对计算密度的影响
          • output size对计算密度的影响
          • channel size对计算密度的影响
          • group convolution对计算密度的影响
          • tensor reshape对计算密度的影响
          • 全连接层对计算密度的影响
      • 对单个模型构建Roofline Model
      • Nsight Compute⼯具⾃动搭建roofline Model
    • 总结
    • 参考

模型部署教程来啦:)

模型部署白皮书❤️‍🔥❤️‍🔥❤️‍🔥

什么是Roofline Model?

想象一下,如果我们想让一辆车跑得更快,我们需要知道它现在能跑多快,是什么在限制它的速度(比如是引擎的问题,还是轮胎的摩擦),以及我们可以做哪些改动来让它跑得更快。在计算机和程序的世界里,我们也有类似的方法来帮助我们理解和提升一个程序的运行速度,这就是所谓的“Roofline Model”(屋顶模型)。

屋顶模型就像是一个图表,帮助我们看到一个程序在特定的计算机上能跑得多快,以及是什么在限制它跑得更快。这个模型被画成一张图,上面有两条线:

  1. 屋顶线(Roofline):这条线像房子的屋顶一样,代表了最快的速度,即计算机的最大性能。你可以把它想象成车能达到的最高速度。这个速度有两部分限制:一部分是计算机处理数据的速度(比如引擎有多强),另一部分是计算机从内存中获取数据的速度(比如路上的限速标志)。

  2. 程序的点:图表上的每一个点代表了一个程序或者程序的一部分。这个点的位置会告诉我们程序现在的速度有多快,以及是什么在限制它——是处理数据的速度,还是获取数据的速度。

其实 Roof-line Model 说的是很简单的一件事:模型在一个计算平台的限制下,到底能达到多快的浮点计算速度。更具体的来说,Roof-line Model 解决的,是“计算量为A且访存量为B的模型在算力为C且带宽为D的计算平台所能达到的理论性能上限E是多少”这个问题。接下来让我们了解一些和Roofline Model相关的基本概念。

算法模型相关指标

计算量
  • 定义:针对单个输入,模型完成一次完整的向前传播所发生的浮点运算个数(FLOPs, floating point operations),也即模型的时间复杂度

  • 计算⽅式: M 2 ∗ K 2 ∗ C i n ∗ C o u t M^2*K^2*C_{in}*C_{out} M2K2CinCout

M: 卷积核输出特征图的H和W。不同的时候可以用Mh, Mw表示 K: 卷积核大小

(严格来说应该乘以2,不然实际上算的是MACs值。MACs、MAdds、FLOPs的区别:FLOPs=2*MACs=2*MAdds,乘累加操作MACs(Multiply‒Accumulate Operations)中 1MACs包含⼀个乘法操作与⼀个加法操作,所以MAdds通常是FLOPs值的⼆分之⼀。但在计算机视觉论⽂中,常常将⼀个乘加组合视为⼀次浮点运算,所以也会常⻅到将MACs值作为Flops的,⽽且常⻅的计算⼯具都是按照不乘以2计算的)

计算峰值

单位是FLOPS (也可以是FLOP/s), 表示计算机每秒可以执行的 floating point operations。是衡 量计算机性能的标准

在这里插入图片描述

参数量

单位是Byte,表示模型中所有 的weights(主要在conv和FC中) 的量。是衡量模型大小的标准。

访存量

针对单个输入,模型完成一次完整的向前传播所发生的内存交换总量(read/write),**也即模型的空间复杂度。**单位:Byte

计算方式:*(每层输入的特征图内存占用+模型参数内存占用+每层输出的特征图内存占用)4,由于模型训练时数据类型一般是float32,所以换算成Byte需要乘以4

M A C s C o n v = M A C s I n p u t + M A C s W c i g h t + M A C s O u t p u t = ( N × I C × I H × I W + O C × I C × K H × K W + N × O C × O H × O W ) × s i z e o f ( d a t a _ t y p e ) \begin{aligned} MACs_{Conv}& =MACs_{Input}+MACs_{Wcight}+MACs_{Output} \\ &=(N\times IC\times IH\times IW+OC\times IC\times KH\times KW+N\times OC\times OH\times OW) \\ &\times sizeof(data\_type) \end{aligned} MACsConv=MACsInput+MACsWcight+MACsOutput=(N×IC×IH×IW+OC×IC×KH×KW+N×OC×OH×OW)×sizeof(data_type)

带宽

单位是Byte/s,全称是memory bandwidth, 表示的是单位时间内可以传输的数据量的多少。是衡量计算机硬件memory性能的一 个标准

带宽跟以下因素有关:

  • memory clock (GHz) :表示的是单位时间内可以read/write的 频率(Hz),一般以GHz为基本单位
  • memory bus width (Byte):如同字面意思,表示的是可以同时读写 的数据多少。单位是Byte
  • memory channel:表示的是通道数量,越多越好

举几个例子:

  • NVIDIA Tesla V100

    • memory: HBM2

    • memory clock: 877 MHz

    • memory interface width: 512 Bytes (4096 bits)

    • => memory bindwidth = 877 MHz * 512 Bytes * 2 = 898GB/s

  • NVIDIA Quadro RTX 6000

    • memory: GDDR6 • memory clock: 1750 MHz
    • memory clock effective: 1750 MHz * 8 = 14Gbps
    • memory interface width: 48 Bytes (384 bits)
    • => memory bindwidth = 14 Gbps * 48 Bytes * 1 = 672GB/s

怎么提高程序的带宽?

  • 硬件层面:

使用更快的存储设备:使用固态硬盘(SSD)而不是传统机械硬盘(HDD)可以显著提高数据读写速度。

增强计算能力:通过使用更快的处理器或增加处理器核心数量来提升处理能力。在多核心系统上,可以并行处理数据以提高效率。

  • 软件层面:

  • 代码优化:通过剖析(Profiling)工具找出程序中的瓶颈,然后针对这些瓶颈进行优化。优化可能包括减少不必要的计算、使用更高效的算法或数据结构等。

  • 并行计算:利用现代处理器的多核心特性,将任务分解成可以并行执行的子任务。对于大规模数据处理,可以考虑使用GPU进行并行计算。

  • 减少数据传输量:如果带宽受限于数据传输,考虑使用数据压缩技术减少传输的数据量。对于网络应用,还可以通过优化通信协议来减少开销。

计算密度

计算密度(Computational intensity, I I I) I = n u m o f F L O P s / b y t e s o f d a t a ( F L O P s / B y t e ) I={numofFLOPs}/{bytesofdata}(FLOPs/Byte) I=numofFLOPs/bytesofdata(FLOPs/Byte),表示每Byte内存交换到底用于多少次浮点运算,计算强度越大,内存使用效率越高。

在这里插入图片描述

设Imax为拐点所对应的强度,是计算平台的计算强度上限。**当I<Imax时,模型的计算性能受限于宽带⼤⼩,处于宽带瓶颈区;当I>Imax时,模型的计算性能瓶颈取决于平台的算⼒,处于计算瓶颈区。**所以,模型的计算强度应尽量⼤于Imax,这样才能最⼤程度利⽤计算平台的算⼒资源,但超过之后就⽆需再追求⽆意义的提升,因为再强性能都只能达到计算平台的算⼒。

以3080 Ampere架构为例计算硬件的roofline model,相关参数如下:

  • Core种类与数量
    • 8704 CUDA cores
    • 272 Tensor cores
    • 68 SMs
  • 计算峰值
    • (FP32) 29.8 TFLOPS
    • (FP16) 119 TFLOPS
    • (INT8) 238 TOPS
  • 带宽
  • 760.32 GB/s
  • 频率
    • 1.7GHz

FP32计算密度

  • 计算峰值 29.8 T F L O P S = 29.8 × 1 0 1 2 F L O P S 29.8 TFLOPS = 29.8 × 10^12 FLOPS 29.8TFLOPS=29.8×1012FLOPS
  • 内存带宽 760.32 G B / s = 760.32 × 1 0 9 b y t e s / s 760.32 GB/s = 760.32 × 10^9 bytes/s 760.32GB/s=760.32×109bytes/s

[ 计算密度 FP32 = 29.8 × 1 0 12 760.32 × 1 0 9   FLOPS/byte ] [ \text{计算密度}_{\text{FP32}} = \frac{29.8 \times 10^{12}}{760.32 \times 10^{9}} \, \text{FLOPS/byte} ] [计算密度FP32=760.32×10929.8×1012FLOPS/byte]

FP16计算密度

  • 计算峰值 119 T F L O P S = 119 × 1 0 1 2 F L O P S 119 TFLOPS = 119 × 10^12 FLOPS 119TFLOPS=119×1012FLOPS
  • 内存带宽 760.32 G B / s = 760.32 × 1 0 9 b y t e s / s 760.32 GB/s = 760.32 × 10^9 bytes/s 760.32GB/s=760.32×109bytes/s

[ 计算密度 FP16 = 119 × 1 0 12 760.32 × 1 0 9   FLOPS/byte ] [ \text{计算密度}_{\text{FP16}} = \frac{119 \times 10^{12}}{760.32 \times 10^{9}} \, \text{FLOPS/byte} ] [计算密度FP16=760.32×109119×1012FLOPS/byte]

INT8计算密度

  • 计算峰值 238 T O P S = 238 × 1 0 1 2 O P S 238 TOPS = 238 × 10^12 OPS 238TOPS=238×1012OPS
  • 内存带宽 760.32 G B / s = 760.32 × 1 0 9 b y t e s / s 760.32 GB/s = 760.32 × 10^9 bytes/s 760.32GB/s=760.32×109bytes/s

[ 计算密度 INT8 = 238 × 1 0 12 760.32 × 1 0 9   OPS/byte ] [ \text{计算密度}_{\text{INT8}} = \frac{238 \times 10^{12}}{760.32 \times 10^{9}} \, \text{OPS/byte} ] [计算密度INT8=760.32×109238×1012OPS/byte]

RTX 3080的计算密度如下:

  • FP32: 约39.19 FLOPS/byte
  • FP16: 约156.51 FLOPS/byte
  • INT8: 约313.03 OPS/byte

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

INT8运算的计算密度最高,意味着在处理INT8数据类型时,相对于内存带宽的限制,GPU能进行更多的计算,这在深度学习推理等场景中非常有用。

TOPS(Tera Operations Per Second)

  • TOPS 主要用于衡量整数(包括定点)操作的性能。
  • 它表示每秒可以执行的万亿次(Tera)操作,通常用于评估AI芯片、DSP(数字信号处理器)或其他专用硬件的性能,特别是在执行非浮点计算任务时。

TFLOPS(Tera Floating Point Operations Per Second)

  • TFLOPS 专注于浮点数运算的性能。
  • 它表示每秒可以执行的万亿次浮点运算,是评价GPU和CPU等计算设备在执行科学计算、图形处理和深度学习等浮点密集型任务性能的关键指标。

注意:Roofline Model是根据理论值计算得到的结果,实际使用的时候需要根据一系列benchmark找到部署架构的真实值。(比如自己写几个计算密集的核函数).因为实际计算过程中还有除算力和带宽之外的其他重要因素,它们也会影响模型的实际性能,这是 Roofline Model 未考虑到的。例如矩阵乘法,会因为 cache 大小的限制、GEMM 实现的优劣等其他限制,导致你几乎无法达到 Roofline 模型所定义的边界(屋顶)。

kernel size对计算密度的影响

定义模型如下:

class CustomConvNet(nn.Module):
    def __init__(self):
        super(CustomConvNet, self).__init__()
        # 定义六层卷积层,卷积核大小分别为1, 3, 5, 7, 9, 11
        # 计算padding,使得输出特征图大小保持为56x56,这里假设stride=1
        # 对于任意卷积核大小k,padding可以设置为(k-1)/2(当k为奇数时)
        self.conv1 = nn.Conv2d(256, 256, kernel_size=1, stride=1, padding=0)
        self.conv2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(256, 256, kernel_size=5, stride=1, padding=2)
        self.conv4 = nn.Conv2d(256, 256, kernel_size=7, stride=1, padding=3)
        self.conv5 = nn.Conv2d(256, 256, kernel_size=9, stride=1, padding=4)
        self.conv6 = nn.Conv2d(256, 256, kernel_size=11, stride=1, padding=5)

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.conv4(x)
        x = self.conv5(x)
        x = self.conv6(x)
        return x

在这里插入图片描述

结论:elementwise conv(1x1 conv)的虽然较少了计算量,但是计算密度也 很低。随着kernel size增大,计算密度增长率逐渐下降

output size对计算密度的影响
from torchstat import stat

import torch
import torch.nn as nn

class UpsampleConvNet(nn.Module):
    def __init__(self):
        super(UpsampleConvNet, self).__init__()
        # 假设初始输入尺寸为7x7, 通过上采样逐步增加特征图大小
        self.conv1 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        # 上采样层,用于增加特征图的维度
        self.upsample = nn.Upsample(scale_factor=2, mode='nearest')
        self.conv2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.conv4 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.conv5 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.conv6 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)

    def forward(self, x):
        x = self.conv1(x)
        x = self.upsample(x) # 14x14
        x = self.conv2(x)
        x = self.upsample(x) # 28x28
        x = self.conv3(x)
        x = self.upsample(x) # 56x56
        x = self.conv4(x)
        x = self.upsample(x) # 112x112
        x = self.conv5(x)
        x = self.upsample(x) # 224x224
        x = self.conv6(x)
        return x

# 创建模型实例
model = UpsampleConvNet()

stat(model, (256, 7, 7))

在这里插入图片描述

结论:output size对计算密度的影响,随着output size变大,计算密度的增 长率逐渐下降

channel size对计算密度的影响
class CustomConvNet(nn.Module):
    def __init__(self):
        super(CustomConvNet, self).__init__()
        # 定义卷积层
        self.conv1 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
        self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1)
        self.conv5 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1)
        # 假设输入特征图大小为56x56,最后一层不改变通道数,仍然输出512通道
        self.conv6 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1)
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.conv4(x)
        x = self.conv5(x)
        x = self.conv6(x)
        return x

在这里插入图片描述

结论:channel size对计算密度的影响,越大的channel size计算密度 越高。

group convolution对计算密度的影响
class GroupConvNet(nn.Module):
    def __init__(self):
        super(GroupConvNet, self).__init__()
        # 定义六个卷积层,卷积核大小均为3,组数依次为32, 16, 8, 4, 2, 1
        self.conv1 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=32)
        self.conv2 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=16)
        self.conv3 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=8)
        self.conv4 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=4)
        self.conv5 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=2)
        self.conv6 = nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1, groups=1) # 普通卷积
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.conv4(x)
        x = self.conv5(x)
        x = self.conv6(x)
        return x

在这里插入图片描述

结论: group convolution对计算密度的影响。depthwise虽然降低了 计算量,但计算密度也下降的很多

tensor reshape对计算密度的影响
  • 计算量: M 2 ∗ K 2 ∗ C i n ∗ C o u t M^2*K^2*C_{in}*C_{out} M2K2CinCout

  • 访存量 : ( K 2 ∗ C i n ∗ C o u t + M 2 ∗ C o u t ) ∗ 4 :(K^{2}*C_{in}*C_{out}+M^{2}*C_{out})*4 :(K2CinCout+M2Cout)4

M: 卷积核输出特征图的H和W。不同的时候可以用Mh,Mw表示
K:卷积核大小

  • 模型中没有tensor reshape

在这里插入图片描述

  • 模型中有3个tensor reshape

在这里插入图片描述

  • 模型中有5个tensor reshape

在这里插入图片描述

结论:过多的tensor reshape会降低模型的计算密度

全连接层对计算密度的影响
  • 计算量: C i n ∗ C o u t C_{in}*C_{out} CinCout
  • 访存量:( C i n ∗ C o u t ) ∗ 4 C_{in}*C_{out})*4 CinCout)4

M:卷积核输出特征图的H和W。不同的时候可以用Mh,Mw表示
K: 卷积核大小

在这里插入图片描述

对单个模型构建Roofline Model

  • 以ResNet18为例

在这里插入图片描述

也可以使用Nsight Compute,可以查看各个kernel的roofline model(当前的实际值而非理论值)和整个模型的roofline model十分的方便。

在这里插入图片描述

Jetson AGX Xavier架构中FP32的计算在10.2FLOPs/byte就计算饱和。所以这些模型 其实都理论上已经计算饱和

到目前讲的是理论值。然而实际上我们会发现:

  • 峰值可能会小于22.4TOPS
  • bandwidth可能会小于137GB/s 需要根据一系列benchmark找到部署架构的真实值。(比如自己写几个计算密集的核函数或者你不想自己写可以康康这个大佬的repo:https://github.com/ekondis/gpumembench)

在这里插入图片描述

Nsight Compute⼯具⾃动搭建roofline Model

⼀般最后跟的代码是可执⾏⽂件,如果是python代码,就需要在前⾯加上编译器的⼆进制⽂件的完整路径,正确的⽰例如下:

ncu --set roofline -o profile_roofline --target-processes all xxx\python.exe xxx.py

不加编译器路径会报以下错误:

==ERROR== The target application is not an executable binary.
==ERROR== If the target application is a script, try prepending the full path to the interpreter binary.

注意:需要以管理员权限运行该条命令,不然会报错:

==ERROR== ERR_NVGPUCTRPERM - The user does not have permission to access NVIDIA GPU Performance Counters on the target device 0. For instructions on enabling permissions and to get more information see https://developer.nvidia.com/ERR_NVGPUCTRPERM

上述命令执行后将会生成文件profile_roofline.ncu-rep,通过Nsight Compute软件打开(这里同样用ResNet34,输入大小为(33232)进行测试)

在这里插入图片描述

选择展示Details页面,选择某一个kernel,然后展开GPU Speed Of Light Throughput选项,就可以看到该kernel的详细统计信息(下图中的Double Precision、Half Precision 和Tensor Core Roofline中没有achived value小圆点是因为实际跑的算法模型数据值是单精度的,所以主要使用的是GPU中的FP32 Core,而FP64 Core、Tensor Core就没有使用到)。

在这里插入图片描述

从summary中对所有kernel的统计概览来看(下图),各个kernel的计算量和内存使用率之间差别较大。

在这里插入图片描述

这里单独从内存占用率最高(73.97%)的一个双击进去为例,roofline模型图如下(peak work、peak traffic可以理解为该kernel运行过程中的最高算力值、最高使用的内存带宽,可见这两个参数的实际值小于官方公布的448.06GB/s),从图上可见实际表现值处于memory-bound区域,而稍微处于斜线下方,说明内存带宽上还没有完全利用完,利用率粗略计算为 39.724 / 0.13 203.148 / 0.48 = \frac{39.724/0.13}{203.148/0.48}= 203.148/0.4839.724/0.13= 72.2%与73.97%基本一致。

在这里插入图片描述

这里只是能看单独某一个kernel的roofline模型,要想要整个模型的效果,可以将所有kernel的各项值取平均在进行计算.

总结

Roofline模型可以帮助选择适合应用程序需求的硬件配置(GPU架构、核心数、频率),也可以依据特定的计算平台选择能最大化利用其算力资源的应用程序。

除此以外,还可以用于根据实际情况下所处的瓶颈区对应用程序进行性能优化。比如在深度学习网络模型中,当模型的计算强度小于平台的计算强度时,模型处于宽带瓶颈区,而为了最大程度发挥计算平台的性能,应尽量避免这种情况。
此时可以对模型结构进行优化或者增加带宽,在训练过程中,对其损失函数进行设计,比如当模型的计算强度低于计算平台的计算强度时,损失函数加上两个计算强度之间的差值再乘以某个系数(鼓励模型在训练过程中增加其计算强度,从而更充分地利用计算平台的算力资源)。这样训练过程中模型的计算强度就会往靠近计算平台的方向变化,从而达到目的。

参考

  • RooflineVyNoYellow.pdf (berkeley.edu)

  • Roofline Model与深度学习模型的性能分析 - 知乎 (zhihu.com)

  • Roofline模型的构建与应用 - 知乎 (zhihu.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网站使用SSL证书有什么好处

SSL证书是一种用于加密在网络上传输的数据以确保安全性和隐私的数字证书。下面我们来谈谈一个网站使用SSL证书后有哪些好处&#xff1a; 首先&#xff0c;使用SSL证书可以保护用户的隐私。在没有SSL证书的情况下&#xff0c;用户的个人信息和敏感数据可能会被黑客窃取或篡改。…

npm安装指定版本,npm删除依赖,卸载依赖

安装指定版本 npm中安装指定的版本号&#xff0c;格式为 ‘包名版本号’ npm install 包名称版本号 --save 例如安装jquery: npm install jquery3.0.0 --save在package.json里面可以看到对应的包&#xff1a; "jquery": "^3.0.0"注意&#xff1a;已有…

基于springboot实现医院药品管理系统项目【项目源码+论文说明】

基于springboot实现医院药品管理系统演示 摘要 身处网络时代&#xff0c;随着网络系统体系发展的不断成熟和完善&#xff0c;人们的生活也随之发生了很大的变化&#xff0c;人们在追求较高物质生活的同时&#xff0c;也在想着如何使自身的精神内涵得到提升&#xff0c;而读书就…

CentOS 重启网络失败service network restart

命令 service network restart 提示 Job for network.service failed because the control process exited with error code. See “systemctl status network.service” and “journalctl -xe” for details. 原因分析 使用journalctl -xe命令查看日志后的具体错误 -- Un…

基于springboot实现疾病防控综合系统项目【项目源码+论文说明】

基于springboot实现疾病防控综合系统演示 摘要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&…

PDPS15---安装过程---常遇问题---分享

目录 问题1 安装失败 1.1 运行第一步出错 1.2 解决 问题2 路径错误 2.1 错误 2.2 解决 问题3 运行失败 3.1 无法找到路径 3.2 原因分析 3.3 解决 问题4 拒绝访问 4.1 出现提示 4.2 分析 4.3 解决 问题5 许可证过期 5.1 PD找不到许可证 5.2 解决 问题1 安装失败…

hypertherm海宝EDGE控制器显示屏工控机维修

海宝工控机维修V3.0/4.0/5.0&#xff1b;hypertherm数控切割机系统MICRO EDGE系统显示屏维修&#xff1b; 美国hypertherm公司mirco edge数控系统技术标准如下&#xff1a; 1&#xff09; p4处理器 2&#xff09; 512mb内存 3&#xff09; 80g硬盘&#xff0c;1.44m内置软驱…

AXI Block RAM 控制器IP核的用法详解

本文描述了如何使用Xilinx的Vivado Design Suite环境中的工具来定制和生成AXI Block RAM (BRAM) IP 核。Vivado Design Suite是一个强大的FPGA设计和开发环境&#xff0c;它允许用户定制和配置各种IP核以适应他们的特定设计需求。 以下是针对如何定制IP核的步骤的简要概述&…

【FX110】2024外汇市场中交易量最大的货币对是哪个?

作为最大、最流动的金融市场之一&#xff0c;外汇市场每天的交易量高达几万亿美元&#xff0c;涉及到数百种货币。不同货币对的交易活跃程度并不一样&#xff0c;交易者需要根据货币对各自的特点去进行交易。 全年外汇市场中涉及美元的外汇交易超过50%&#xff01; 实际上&…

docker学习笔记(四)制作镜像

目录 第1步&#xff1a;编辑Dockerfile 第2步&#xff1a;编辑requirements.txt文件 第3步&#xff1a;编辑app.py文件&#xff0c;我们的程序文件 第4步&#xff1a;生成镜像文件 第5步&#xff1a;使用镜像&#xff0c;启动容器 第6步&#xff1a; 启动redis容器、将容器…

开启智慧生活,家政服务触手可及——家政小程序全新上线

繁忙生活中的贴心助手 在快节奏的现代生活中&#xff0c;我们时常为家庭琐事所困扰&#xff0c;无暇享受生活的美好。为了帮助您解决这一难题&#xff0c;我们倾力打造了一款家政小程序&#xff0c;让您的生活更加轻松、便捷。 家政小程序&#xff0c;您的生活管家 1. 全方位…

社媒营销中的截流获客是怎么一回事?

如果你要问&#xff0c;现在做社媒营销是通过哪些方式进行引流的&#xff0c;那么必然有一种是截流&#xff0c;顾名思义也就是分取别人的流量&#xff0c;方法其实很简单&#xff0c;主要分为两种&#xff1a;&#xff08;1&#xff09;抓取别人的粉丝出来进行群发私信&#x…

nestjs 全栈进阶--Module和Provider的循环依赖

视频教程 21_nest中的循环依赖_哔哩哔哩_bilibili 1. 循环依赖 当两个类相互依赖时&#xff0c;就会发生循环依赖。比如 A 类需要 B 类&#xff0c;B 类也需要 A 类。Nest中 模块之间和 提供器之间也可能会出现循环依赖。 nest new dependency -p pnpm nest g res aaa --n…

【Java EE】网络原理——UDP

目录 1.应用层 2.传输层 2.1端口号 2.1.1端口号的范围划分 2.1.2一个端口号可以被多个进程绑定吗&#xff1f; 2.1.3一个进程可以绑定多个端口号吗&#xff1f; 3.UDP协议 3.1UDP的格式 3.1.1 UDP的源端口号 3.1.2 UDP的目的端口号 3.1.3 UDP长度 3.1.4UDP校验和 3…

springboot项目中前端页面无法加载怎么办

在springboot前后端分离的项目中&#xff0c;经常会出现前端页面无法加载的情况&#xff08;比如&#xff1a;前端页面为空白页&#xff0c;或者出现404&#xff09;&#xff0c;该怎么办&#xff1f;&#xff1f;&#xff1f; 一个简单有效的方法&#xff1a;&#xff1a; 第…

24 | MySQL是怎么保证主备一致的?

MySQL 主备的基本原理 内部流程 备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的: 在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始…

钉钉群定时发送消息1.0软件【附源码】

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 有时候需要在钉钉群里提醒一些消息。要通知的群成员又不方便用定时钉的功能&#xff0c;所以写了这么一个每日定时推送群消息的工具。 易语言程序&#xff0c;附上源码与模块&#x…

【记录42】centos 7.6安装nginx教程详细教程

环境&#xff1a;腾讯云centos7.6 需求&#xff1a;安装nginx-1.24.0 1. 切入home文件 cd home 2. 创建nginx文件 mkdir nginx 3. 切入nginx文件 cd nginx 4. 下载nginx安装包 wget https://nginx.org/download/nginx-1.24.0.tar.gz 5. 解压安装包 tar -zxvf nginx-1.24.0.…

ESD静电问题 | 选型TVS单向还是双向?

【转自微信公众号&#xff1a;Amazing晶炎科技】

Mysql进阶-索引篇

Mysql进阶 存储引擎前言特点对比 索引介绍常见的索引结构索引分类索引语法sql分析索引使用原则索引失效的几种情况sql提示覆盖索引前缀索引索引设计原则 存储引擎 前言 Mysql的体系结构&#xff1a; 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接…