GPU虚拟化和算力隔离探讨

1. 术语介绍

术语

全称

说明

GPU

Graphics Processing Unit

显卡

CUDA

Compute Unified Device Architecture

英伟达2006年推出的计算API

VT/VT-x/VT-d

Intel Virtualization Technology

-x表示x86 CPU,-d表示Device

SVM

AMD Secure Virtual Machine

AMD的等价于Intel VT-x的技术

EPT

Extened Page Table

Intel的CPU虚拟化中的页表虚拟化硬件支持

NPT

Nested Page Table

AMD的等价于Intel EPT的技术

SR-IOV

Single Root I/O Virtualization

PCI-SIG 2007年推出的PCIe虚拟化技术

PF

Physical Function

物理卡

VF

Virtual Function

SR-IOV的虚拟PCIe设备

MMIO

Memory Mapped I/O

设备上的寄存器或存储,CPU以内存读写指令来访问

UMD

User Mode Driver

GPU的用户态驱动程序

KMD

Kernel Mode Driver

GPU的PCIe驱动

GVA

Guest Virtual Address

VM中的CPU虚拟地址

GPA

Guest Physical Address

VM看到的物理地址

HPA

Host Physical Address

Host看到的物理地址

IOVA

I/O Virtual Address

设备发出去的DMA地址

PCIe TLP

PCIe Transaction Layer Packet

BDF

Bus/Device/Function

一个PCIe/PCI功能的ID

MPT

Mediated Pass-Through

受控直通,一种设备虚拟化的实现方式

MDEV

Mediated Device

Linux中的MPT实现

PRM

Programming Rerference Manual

硬件的编程手册

MIG

Multi-Instance GPU

Ampere架构的高端GPU如A100、A30支持的一种硬件partition方案

2. GPU虚拟化的历史和谱系

GPU天然适合向量计算。最常用的情景及API:

场景

API

游戏渲染

OpenGL/OpenGL ES,DirectX,Vulkan,Metal

媒体编解码

VAAPI,VDPAU

深度学习计算

CUDA,OpenCL

此外还有AES加密、哈希等场景,例如近些年来的挖矿。渲染是GPU诞生之初的应用: GPU的"G"就是Graphics —— 图形。

桌面、服务器级别的GPU,长期以来仅有三家厂商:

  1. 英伟达:GPU王者。主要研发力量在美国和印度。

  2. AMD/ATI:ATI被AMD收购。渲染稍逊英伟达,计算的差距更大。

  3. Intel: 长期作为集成显卡存在,2020开始推出独立显卡。


2006这一年,GPU工业界发生了三件大事: ATI被AMD收购;nVidia黄仁勋提出了CUDA计算;Intel宣布要做独立显卡。

如同经常发生的,这些事有成功有失败: Intel很快就放弃了它的独立显卡,直到2018才终于明白过来、自己放弃的到底是什么,开始决心生产独立显卡;AMD整合ATI不太成功,整个公司差点被拖死,危急时股票跌到1.8美元;而当时不被看好的CUDA,则在几年后取得了不可思议的成功。

从2012年开始,人工智能领域的深度学习方法开始崛起,此时CUDA受到青睐,并很快统治了这个领域。

3. 系统虚拟化和OS虚拟化

系统虚拟化演化之路,起初是和GPU的演化完全正交的:

  • 1998年,VMWare公司成立,采用Binary Translation方式,实现了系统虚拟化。

  • 2001年,剑桥大学Xen Source,提出了PV虚拟化(Para-Virtualization),亦即Guest-Host的主动协作来实现虚拟化。

  • 2005年,Intel提出了VT,最初实现是安腾CPU上的VT-i (VT for Itanium),很快就有了x86上的VT-x。

  • 2007年,Intel提出了VT-d (VT for Device),亦即x86上的IOMMU。

  • 2008年,Intel提出了EPT,支持了内存虚拟化。

  • 2010年,Linux中的PV Hypervisor lguest的作者,Rusty Russell(他更著名的作品是iptables/netfilter),提出了VirtIO,一种Guest-Host的PV设备虚拟化方案。


应该可以说,在PV时代和Binary Translation时代,虚拟化是很危险的。只有当VT在硬件层面解决了CPU的隔离、保证了安全性之后,公有云才成为可能。VT-x于2005~2006年出现,亚马逊AWS于2006年就提出云计算,这是非常有远见的。

系统的三个要素: CPU,内存,设备。CPU虚拟化由VT-x/SVM解决,内存虚拟化由EPT/NPT解决,这些都是非常确定的。但设备虚拟化呢?它的情况要复杂的多,不管是VirtIO,还是VT-d,都不能彻底解决设备虚拟化的问题,这些我们稍后还会谈到。


除了这种支撑完整OS的系统虚拟化,还有一种也往往被称作「虚拟化」的方式: 从OS级别,把一系列的libirary和process捆绑在一个环境中,但所有的环境共享同一个OS Kernel。

严格来说,这种容器技术,和以KVM为代表的系统虚拟化,有着本质的区别。随着容器的流行,「虚拟化」这个术语,也被用来指称这种OS级别的容器技术。因此我们也从众,把它也算作虚拟化的一种 —— 只不过为了区分,称之为OS虚拟化。

这种OS虚拟化最初于2005年,由Sun公司在Solaris 10上实现,名为「Solaris Zone」。Linux在2007~2008开始跟进,接下来有了LXC容器等;到了2013年,Docker横空出世,彻底改变了软件分发的生态,成为事实上的标准。

4. GPU虚拟化的谱系

4.1. 作为PCIe设备的GPU

不考虑嵌入式平台的话,那么,GPU首先是一个PCIe设备。GPU的虚拟化,还是要首先从PCIe设备虚拟化角度来考虑。

那么一个PCIe设备,有什么资源?有什么能力?

2种资源:

  • 配置空间

  • MMIO

  • (有的还有PIO和Option ROM,此略)

2种能力:

  • 中断能力

  • DMA能力


一个典型的GPU设备的工作流程是:

  • 应用层调用GPU支持的某个API,如OpenGL或CUDA

  • OpenGL或CUDA库,通过UMD (User Mode Driver),提交workload到KMD (Kernel Mode Driver)

  • KMD写CSR MMIO,把它提交给GPU硬件

  • GPU硬件开始工作... 完成后,DMA到内存,发出中断给CPU

  • CPU找到中断处理程序 —— KMD此前向OS Kernel注册过的 —— 调用它

  • 中断处理程序找到是哪个workload被执行完毕了,...最终驱动唤醒相关的应用

4.2. PCIe直通

我们首先来到GPU虚拟化的最保守的实现: PCIe设备直通

如前述,一个PCIe设备拥有2种资源、2种能力。你把这2种资源都(直接或间接地)交给VM、针对这2种能力都把设备和VM接通,那么,VM就能完整使用这个PCIe设备,就像在物理机上一样。这种方案,我们称之为PCIe Pass-Through(PCIe直通)。它只能1:1,不支持1:N。其实并不能算真正的虚拟化,也没有超卖的可能性。

VM中,使用的是原生的GPU驱动。它向VM内核分配内存,把GPA填入到GPU的CSR,GPU用它作为IOVA来发起DMA访问,VT-d保证把GPA翻译为正确的HPA,从而DMA到达正确的物理内存。

PCIe协议,在事务层(Transaction Layer),有多种TLP,DMA即是其中的一类: MRd/MWr。在这种TLP中,必须携带发起者的Routing ID,而在IOMMU中,就根据这样的Routing ID,可以使用不同的IOMMU页表进行翻译。


很显然,PCIe直通只能支持1:1的场景,无法满足1:N的需求。

4.3. SR-IOV

那么,业界对1:N的PCIe虚拟化是如何实现的呢?我们首先就会想到SR-IOV。SR-IOV是PCI-SIG在2007年推出的方案,目的就是PCIe设备的虚拟化。SR-IOV的本质是什么?考虑我们说过的2种资源和2种能力,来看看一个VF有什么:

  • 配置空间是虚拟的(特权资源)

  • MMIO是物理的

  • 中断和DMA,因为VF有自己的PCIe协议层的标识(Routing ID,就是BDF),从而拥有独立的地址空间。

那么,什么设备适合实现SR-IOV?其实无非是要满足两点:

  • 硬件资源要能partition好

  • 无状态(至少要接近无状态)

常见PCIe设备中,最适合SR-IOV的就是网卡了: 一或多对TX/RX queue + 一或多个中断,结合上一个Routing ID,就可以封装为一个VF。而且它是近乎无状态的。

试考虑NVMe设备,它的资源也很容易partition,但是它有存储数据,因此在实现SR-IOV方面,就会有更多的顾虑。


回到GPU虚拟化: 为什么2007年就出现SR-IOV规范、直到2015业界才出现第一个「表面上的」SR-IOV-capable GPU【1】?这是因为,虽然GPU基本也是无状态的,但是它的硬件复杂度极高,远远超出NIC、NVMe这些,导致硬件资源的partition很难实现。


注释
【1】 AMD S7150 GPU。腾讯云GA2机型使用。 表面上它支持SR-IOV,但事实上硬件只是做了VF在PCIe层的抽象。Host上还需要一个Virtualization-Aware的pGPU驱动,负责VF的调度。

4.4. API转发

因此,在业界长期缺乏SR-IOV-capable GPU、又有强烈的1:N需求的情形下,就有更high-level的方案出现了。我们首先回到GPU应用的场景:

  1. 渲染(OpenGL、DirectX,etc.)

  2. 计算(CUDA,OpenCL)

  3. 媒体编解码(VAAPI...)

业界就从这些API入手,在软件层面实现了「GPU虚拟化」。以AWS Elastic GPU为例:

  • VM中看不到真的或假的GPU,但可以调用OpenGL API进行渲染

  • 在OpenGL API层,软件捕捉到该调用,转发给Host

  • Host请求GPU进行渲染

  • Host把渲染的结果,转发给VM


API层的GPU虚拟化是目前业界应用最广泛的GPU虚拟化方案。它的好处是:

  • 灵活。1:N的N,想定为多少,软件可自行决定;哪个VM的优先级高,哪个VM的优先级低,同理。

  • 不依赖于GPU硬件厂商。微软、VMWare、Citrix、华为……都可以实现。这些API总归是公开的。

  • 不限于系统虚拟化环境。容器也好,普通的物理机也好,都可以API转发到远端。

缺点呢?

  • 复杂度极高。同一功能有多套API(如渲染的DirectX和OpenGL),同一套API还有不同版本(如DirectX 9和DirectX 11),兼容性就复杂的要命。以业界著名某厂商为例,其VDI团队就200多人的规模。

  • 功能不完整。计算渲染媒体都支持的API转发方案,还没听说过。并且,编解码甚至还不存在业界公用的API!【1】


注释
【1】 Vulkan的编解码支持,spec刚刚添加,有望被所有GPU厂商支持。见下「未来展望」部分。

4.5. MPT/MDEV/vGPU

鉴于这些困难,业界就出现了SR-IOV、API转发之外的第三种方案。我们称之为MPT(Mediated Pass-Through,受控的直通)。 MPT本质上是一种通用的PCIe设备虚拟化方案,甚至也可以用于PCIe之外的设备。它的基本思路是:

  • 敏感资源如配置空间,是虚拟的

  • 关键资源如MMIO(CSR部分),是虚拟的,以便trap-and-emulate

  • 性能关键资源如MMIO(GPU显存、NVMe的CMB等),硬件partition后直接赋给VM

  • Host上必须存在一个Virtualization-Aware的驱动程序,以负责模拟和调度,它实际上是vGPU的device-model

这样,VM中就能看到一个「看似」完整的GPU PCIe设备,它可以attach原生的GPU驱动。以渲染为例,vGPU的工作流程是:

  • VM中的GPU驱动,准备好一块内存,保存的是渲染workload

  • VM中的GPU驱动,把这块内存的物理地址(GPA),写入到MMIO CSR中

  • Host/Hypervisor/驱动: 捕捉到这次的MMIO CSR写操作,拿到了GPA

  • Host/Hypervisor/驱动: 把GPA转换成HPA,并pin住相应的内存页

  • Host/Hypervisor/驱动: 把HPA(而不是GPA),写入到pGPU的真实的MMIO CSR中

  • pGPU工作,完成这个渲染workload,并发送中断给驱动

  • 驱动找到该中断对应哪个workload —— 当初我是为哪个vGPU提交的这个workload? —— 并注入一个虚拟的中断到相应的VM中

  • VM中的GPU驱动,收到中断,知道该workload已经完成,结果已在内存中


这就是nVidia GRID vGPU、Intel GVT(KVMGT、XenGT)的基本实现思路。一般认为graphics stack是OS中最复杂的,加上虚拟化之后复杂度更是暴增,随便什么地方出现BUG,调试起来都是无比痛苦。但只要稳定下来,这种MPT方案,就能兼顾1:N灵活性、渲染计算媒体的完整性、高性能...是不是很完美?

其实也不是。

该方案最大的缺陷,是必须有一个pGPU驱动,负责vGPU的模拟和调度工作。逻辑上它相当于一个实现在内核态的device-model。而且,由于GPU硬件通常并不公开其PRM,所以事实上就只有GPU厂商才有能力提供这样的Virtualization-Aware pGPU驱动。以nVidia GRID vGPU方案为例,GPU硬件卖给我们时nVidia收了一次钱,GRID vGPU方案在腾讯云上部署后,客户使用vGPU时,nVidia还要再收一次钱!

4.6. SR-IOV: revisited

我们重新回到GPU的SR-IOV。AMD从S7150开始、英伟达从Turing架构开始,数据中心GPU都支持了SR-IOV。但是again,它不是NIC那样的SR-IOV,它需要Host上存在一个vGPU的device-model,来模拟从VM来的VF访问。

所以事实上,到目前为止,GPU的SR-IOV仅仅是封装了PCIe TLP层的VF路由标识、从而规避了runtime时的软件DMA翻译,除此之外,和基于MDEV的MPT方案并无本质的不同。

4.7. 谱系表

在介绍完了上述的这些方案后,我们重新看下CUDA计算、OpenGL渲染两种场景的软件栈,看看能发现什么:

CUDA计算stack:

OpenGL渲染Stack:

可以看出,从API library开始,直到GPU硬件,Stack中的每一个阶段,都有被截获、转发的可能性。甚至,一概称之为「API转发」是不合适的 —— 以GRID vGPU、GVT-g为例的DEV转发,事实上就是MPT,和任何API都没有关系。

5. 容器GPU虚拟化

首先,我们这里谈到的,都是nVidia生产的GPU、都只考虑CUDA计算场景。其次,这里的虚拟化是OS虚拟化的容器技术,不适用于KATA这样的基于系统虚拟化的安全容器。

5.1. CUDA的生态

CUDA开发者使用的,通常是CUDA Runtime API,它是high-level的;而CUDA Driver API则是low-level的,它对程序和GPU硬件有更精细的控制。Runtime API是对Driver API的封装。

CUDA Driver即是UMD,它直接和KMD打交道。两者都属于NVIDIA Driver package,它们之间的ABI,是NVIDIA Driver package内部的,不对外公开。

英伟达软件生态封闭:

  • 无论是nvidia.ko,还是libcuda.so,还是libcudart,都是被剥离了符号表的

  • 大多数函数名是加密替换了的

  • 函数调用不直接进行,而是大量使用了函数指针,进行变换和跳转

  • 代码中随处检查栈深度,防止插入函数调用


以nvidia.ko为例,为了兼容不同版本的Linux内核API,它提供了相当丰富的兼容层,于是也就开源了部分代码:

这个26M大小的、被剥离了符号表的nv-kernel.o_binary,就是GPU驱动的核心代码,所有的GPU硬件细节都藏在其中。

5.2. vCUDA和阿里云cGPU

vCUDA架构图:

cGPU架构图:

不同厂商的隔离行对比

5.3. GPU池化和算力隔离

GPU池化的谱系:

以CUDA API level的转发池化方案、趋动科技公司的Orion为例,它到了GPU所在的后端机器上,由于一个GPU卡可能运行多个GPU任务,这些任务之间,依然需要有算力隔离。Orion为了实现这一点,在后端默认启用了nVidia MPS —— 也就是故障隔离最差的方案。这会导致什么?一个VM里的CUDA程序越界访问了显存,一堆风马牛不相及的VM里的CUDA应用就会被杀死。

所以很显然,GPU池化也必须以同时满足故障隔离和算力隔离的方案作为基础。

5.4. 算力隔离的本质

从对阿里云cGPU的介绍上、从Orion池化方案的后端缺陷上,都可以看出:算力隔离是GPU虚拟化、GPU池化的关键。如果没有算力隔离,不管虚拟化损失有多低,都会导致其方案价值变低(例如: cGPU);而Orion,宁肯牺牲实例间的故障隔离,也要用MPS实现算力隔离 —— 这是一种自毁口碑的行为,但至少,对尚未意识到MPS致命缺陷的小白客户来说,还能够看到算力隔离的存在。

英伟达GPU提供了丰富的硬件特性,支持硬件partition,支持Time Sharing。

1. Hardware Partition,亦即: 空分

Ampere架构的A100、A30 GPU所支持的MIG,即是一种Hardware Partition。其资源隔离、故障隔离都是硬件实现的 —— 这是无可争议的隔离性最好的方案。它的问题是不灵活: 只有高端GPU支持;只支持CUDA计算;A100只支持7个MIG实例。

2. nVidia MPS

除了MIG,算力隔离表现最优秀的,是MPS —— 它通过将多个进程的CUDA Context,合并到一个CUDA Context中,省去了Context Switch的开销,也在Context内部实现了算力隔离。如前所述,MPS的致命缺陷,是把许多进程的CUDA Context合并成一个,从而导致了故障传播。所以尽管它的算力隔离效果极好,但长期以来工业界使用不多,多租户场景尤其如此。

3. Time Sharing,亦即: 时分

基于Engine的Context Switch。不管是哪一代的GPU,其Engine都是支持多任务调度的。一个OS中同时运行多个CUDA任务,这些任务就是在以Time Sharing的方式共享GPU。

鉴于MIG的高成本和不灵活、MPS故障隔离方面的致命缺陷,事实上就只剩下一种可能:Time Sharing。唯一的问题是,如何在原厂不支持的情况下,利用Time Sharing支持好算力隔离、以保证QoS。这也是学术界、工业界面临的最大难题。

5.4.1. GPU microarchitecture和chip

真正决定GPU硬件以何种方式工作的,是chip型号。不管是GRID Driver还是Tesla Driver,要指挥GPU硬件工作,就要首先判断GPU属于哪种chip,从而决定用什么样的软硬件接口来驱动它。

5.4.2. PFIFO: GPU Scheduling Internals

PFIFO架构:

概念解释:

PFIFO: GPU的调度硬件,整体上叫PFIFO。

Engine: 执行某种类型任务的GPU硬件单元。常见engine有:

  • PGRAPH CUDA/Graphics

  • PCOPY Copy Engine

  • PVENC Video Encoding

  • PVDEC Video Decoding

  • ...

最重要的就是PGRAPH Engine,它是CUDA和渲染的硬件执行单元。

Channel: GPU暴露给软件的,对Engine的抽象。一个app可以对应一或多个channels,执行时由GPU硬件把一个一个的channel,放在一个一个的engine上执行。channel是软件层的让GPU去执行的最小调度单位。

TSG: Timeslice Group。

由一组(一或多个)channel(s)组成。一个TSG共享一个context,且作为一个调度单位被GPU执行。

runlist: GPU调度的最大单位。调度时,GPU通常是从当前runlist的头部摘取TSG或channel
来运行。因此,切换runlist也意味着切换active TSG/channel。

PBDMA: pushbuffer DMA
GPU上的硬件,用于从Memory中获取pushbuffer。

Host

GPU上和SYSMEM打交道的部分(通过PCIe系统)。PBDMA是Host的一部分。
注意,Host是Engine和SYSMEM之间的唯一桥梁。

Instance Block

每个Channel对应一个Instance Block,它包含各个Engine的状态,用于Context Switch时的Save/Restore;包含GMMU pagetable;包含RAMFC —— 其中包括UMD控制的USERD。

5.4.3 runlist/TSG/channel的关系

1. Tesla驱动为每个GPU,维护一或多个runlist,runlist或位于VIDMEM,或位于SYSMEM

2. runlist中有很多的entry,每个entry是一个TSG或一个channel

  • 一个TSG是multi-channel或single-channel的

  • 一个channel必定隶属于某个TSG

3. 硬件执行TSG或channel,当遇到以下情景之一时,进行Context Switch:

  • 执行完毕

  • timeslice到了 —— Tesla Driver默认2ms

  • 发生了preemption

5.4.4 pending channel notification

pending channel notification是USERD中的机制。UMD可以利用它通知硬件: 某个channel有了新的任务了【1】。这样,GPU硬件在当前channel被切换后(执行完毕、或timeslice到了),就会执行相应的channel。


注释
【1】 不同chip,实现有所不同。

5.4.5 从硬件调度看GRID vGPU

GRID vGPU支持3种scheduler:

1. Best Effort: 所有vGPU的任务随意提交,GPU尽力执行。

【现象】 如果启动了N个vGPU,它们的负载足够高,那么结果就是均分算力。
【原理】所有的vGPU使用同一个runlist。runlist内,还是按照channel为粒度进行调度。如同在native机器上运行多个CUDA任务一样。


2. Equal Share: 所有vGPU严格拥有同样的GPU配额

【现象】如果启动了N个vGPU,它们严格拥有相同的算力,不管是否需要这么多。
【原理】为每个vGPU维护一个runlist。当它的timeslice过了,GRID Host Driver会写GPU寄存器,触发当前runlist被抢占、下一个runlist被调度。


3. Fixed Share: 每个vGPU有自己固定的GPU配额

【现象】每个vGPU严格按照创建时的规格来分配算力。
【原理】Ditto.

5.5 腾讯云qGPU简介

qGPU == QoS GPU。它是业界唯一真正实现了故障隔离、显存隔离、算力隔离、且不入侵生态的容器GPU共享的技术。

5.5.1 qGPU基本架构

qGPU基本架构和友商cGPU类似:

5.5.2 qGPU QoS效果

注释

  1. 测试数据来自T4(chip: TU104)。

  1. 两个PoD的配比为2:1,横坐标为batch值,纵坐标为实际运行时两个PoD的算力比例。可以看到,batch较小时,负载较小,无法反映算力比例; 随着batch的增大,MPS和qGPU都趋近理论值2,vCUDA也偏离不远,但缺乏QoS的cGPU则逐渐趋近1 —— 两个PoD相等。

6. GPU虚拟化: 未来展望

2021以来,GPU工业界发生了一些变化,e.g.:

英伟达QoS被攻破

英伟达在CUDA计算领域占据压倒性的优势,因此它对提升GPU利用率并无兴趣: MPS只是玩票性质的;MIG昂贵而又不灵活;即使是GRID vGPU,也在灵活性上远远没有做到它本应做到的。

长期以来,学术界和工业界付出了大量的努力,尝试在英伟达不支持QoS的前提下,实现某种程度的算力隔离。遗憾的是,这些努力,要么集中在CUDA API层,能够做到一定的算力隔离,但同样会带来副作用;要么尝试在low-level层面突破 —— 但不幸全都失败了。

qGPU是十几年来在英伟达GPU上实现QoS的最大突破。基于它:

  • 腾讯云TKE的多容器共享GPU,将无悬念地领先整个工业界

  • 在线推理 + 离线训练的混布,成为可能

  • GPU池化的后端实现,不管采用哪种方案,都有了坚实的基础

  • Linux/Android场景的渲染,目前需求小众,但技术基础已经有了

Vulkan Spec支持了video encode/decode

很可能,编解码API不统一的乱象即将终结,这对API转发方案有很大的意义。不远的将来,或许某种API方案的vGPU会成为主流。Google在社区的一些活动表明,很可能它就有这样的计划。

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

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

相关文章

ASP.NET视频点播系统的设计与实现

摘 要 本文阐述了基于WEB的交互式视频点播系统的协议原理、软件结构和设计实现。本视频点播系统根据流媒体传输原理,在校园局域网的基础上模拟基于Web的视频点播系统,实现用户信息管理、视频文件的添加、删除、修改及在线播放和搜索功能。本系统是一个…

6.块元素和行内元素

块元素 无论内容多少,该元素独占一行(p、 h1-h6…) 例子如下图 行内元素 内容撑开宽度,左右都是行内元素的可以排在一排(a、 strong、 em …) 例子如下 感谢您的观看,能和您一起学习是我最大的荣幸! 文章学习资料:…

【快速入门Linux】10_Linux命令—Vi编辑器

文章目录 一、vi 简介1.1 vi1.2 vim1.3查询软连接命令(知道) 二、打开和新建文件(重点)2.1 打开文件并且定位行2.2 异常处理 三、vi三种工作模式(重点)3.1 末行模式-命令 四、常用命令4.0 命令线路图4.1 移…

url对象---了解url的结构

什么是url url是网页网页的地址,通过一个url我们可以访问到网页,同时url也可以用来引用文件(txt,json,jpg,js,css,html),所以你可以理解成url是一个指示器,它可以指向一个文件,网页,图片,或者音…

《网络安全技术 网络安全众测服务要求》

近日,全国网络安全标准化技术委员会发布《网络安全技术 网络安全众测服务要求》(GB/T 43741-2024,以下简称“众测服务要求”),并将在2024年11月1日正式实施。 《众测服务要求》确立了网络安全众测服务的角色及其职责&…

【skill】移动云服务器80端口

上个月玩CentOS7,提到alist端口问题,https://www.bilibili.com/read/cv33662501/ 云服务器不能被外网访问的原因 1 云服务器没放行端口 2 防火墙没放行端口 3 配置了端口转发 4 浏览器不支持搭建的网页 5 端口被其他软件占用 移动10086云服务的80端口…

ubuntu ros noetic 编译 ORB_SLAM2 过程记录

1. 连接 eigen库 sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen 2. opencvx 修改 CMakeList.txt 中的 find_package open cv版本 修改 include/orbExtracter.h 文件为&#xff1a; //#include <opencv2/opencv.hpp> #include<opencv2/imgproc/imgpro…

用魔法打败魔法:用360解除chrome浏览器的360主页

面临的问题&#xff1a; 试了108种方法都是不好使的。 后来看到&#xff1a; https://blog.csdn.net/qq_30267617/article/details/120373704 的介绍&#xff0c;发现可以呀。 三个步骤 步骤1 单击“功能大全” 步骤2 单击“主页防护” 步骤3 在这里更改。

数组不为人知的一面,sizeof与strlen的区分

数组有另外一种表达方式&#xff0c;接下来我用代码的形式展现出来&#xff1a; sizeof 是一个操作符。 是用来计算变量&#xff08;类型&#xff09;所占内存空间大小&#xff0c;不关注内存中存放的具体内容。 单位是字节。 strlen 是一个库函数&#xff0c;是专门求字符…

【计算机毕业设计】基于SpringBoot+Vue智能停车计费系统设计与实现

目录 一、项目介绍 二、项目主要技术 三、系统功能结构设计 四、系统详细功能的实现 4.1 前台功能实现 4.2 管理员模块实现 4.3 用户后台模块实现 五、实现代码 一、项目介绍 该系统采用了java技术、SpringBoot 框架&#xff0c;连接MySQL数据库&#xff0c;具有较高…

深度学习之基于Vgg16卷积神经网络印度交警手势识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着智能交通系统的不断发展&#xff0c;手势识别技术在其中扮演着越来越重要的角色。特别是在印度等…

【研发日记】Matlab/Simulink避坑指南(十一)——Delay周期Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结归纳 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南(六)——字节分割Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(七)——数据溢出钳位Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指…

Redis高并发可用-主从复制,集群

Redis高并发可用 1 复制 默认情况下&#xff0c;Redis都是主节点。每个从节点只能有一个主节点&#xff0c;而主节点可以同时具有多个从节点。复制的数据流是单向的&#xff0c;只能由主节点复制到从节点。 1.1 复制的拓扑结构 一主一从&#xff1a; 主一从结构是最简单的…

web3风格的网页怎么设计?分享几个,找找感觉。

web3风格的网站是指基于区块链技术和去中心化理念的网站设计风格。这种设计风格强调开放性、透明性和用户自治&#xff0c;体现了Web3的核心价值观。 以下是一些常见的Web3风格网站设计元素&#xff1a; 去中心化标志&#xff1a;在网站的设计中使用去中心化的标志&#xff0…

js[黑马笔记]

js基础 基础语法 输入输出 变量 数组 常量 数据类型 类型转换 运算符 语句 数组 函数 调用方式 函数名() 匿名函数 使用: 1.函数表达式 2.立即执行函数 对象 内置对象 web API DOM document object Model元素操作 获取元素 设置元素 定时器 DOM事件基础 事件监听 事件类…

UDP编程流程(UDP客户端、服务器互发消息流程)

一、UDP编程流程 1.1、 UDP概述 UDP&#xff0c;即用户数据报协议&#xff0c;是一种面向无连接的传输层协议。相比于TCP协议&#xff0c;UDP具有以下特点&#xff1a; 速度较快&#xff1a;由于UDP不需要建立连接和进行复杂的握手过程&#xff0c;因此在传输数据时速度稍快…

约瑟夫问题新解法

前言 又碰到了约瑟夫问题&#xff0c;这样的题目本来用环形链表模拟的话就能做出来。然而&#xff0c;最近新学习了一种做法&#xff0c;实在是有点震惊到我了。无论是思路上&#xff0c;还是代码量上&#xff0c;都是那么的精彩。就想也震惊一下其他人。谁能想到原来模拟出来四…

【面试经典 150 | 分治】合并 K 个升序链表

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;顺序合并方法二&#xff1a;分治合并方法三&#xff1a;使用优先队列合并 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目…

知识图谱推动条件

文章目录 计算设备及硬件的发展可用数据规模的提升算法演进数据/知识检索需求攀升开源知识库建设专业人才培养 计算设备及硬件的发展 知识图谱的发展离不开计算硬件的支撑&#xff0c;特别是知识图谱构建、推理、应用过程中的机器学习算法的训练和预测等过程&#xff0c;对计算…

XYCTF2024 RE ez unity 复现

dll依然有加壳 但是这次global-metadata.dat也加密了&#xff0c;原工具没办法用了&#xff0c;不过依然是可以修复的 a. 法一&#xff1a;frida-il2cpp-bridge 可以用frida-il2cpp-bridge GitHub - vfsfitvnm/frida-il2cpp-bridge: A Frida module to dump, trace or hijac…