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在社区的一些活动表明,很可能它就有这样的计划。

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

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

相关文章

RabbitMQ入门教学(浅入浅出)

进程间通信 互联网的通讯时网络的基础,一般情况下互联网的资源数据对储存在中心服务器上,一般情况下个体对个体的访问仅限于局域网下,在公网即可完成资源的访问,如各种网站资源,下载资源,种子等。网络通讯…

小程序地理位置接口开通90%小白都避不开的误区

小程序地理位置接口有什么功能? 目前小程序的地理位置接口已经调整为审核制了,也就是说我们开发者如果小程序需要用到getlocation等接口的话,需要先在小程序后台进行开通申请,提交相关证明材料才可以获得接口使用权限。 小程序地理…

GPT-1

GPT 系列是 OpenAI 的一系列预训练模型,GPT 的全称是 Generative Pre-Trained Transformer,顾名思义,GPT 的目标是通过 Transformer,使用预训练技术得到通用的语言模型。目前已经公布论文的有 GPT-1、GPT-2、GPT-3。 最近非常火的…

Go协程的底层原理(图文详解)

为什么要有协程 什么是进程 操作系统“程序”的最小单位进程用来占用内存空间进程相当于厂房,占用工厂空间 什么是线程 进程如果比作厂房,线程就是厂房里面的生产线: 每个进程可以有多个线程线程使用系统分配给进程的内存,线…

【linux-汇编-点灯之思路-程序】

目录 1. ARM汇编中的一些注意事项2. IMXULL汇编点灯的前序:3. IMXULL汇编点灯之确定引脚:4. IMXULL汇编点灯之引脚功能编写:4.1 第一步,开时钟4.2 第二步,定功能(MUX)4.3 第三步,定电…

服务器遭受攻击后的黑洞状态应对策略及防护机制解析

引言 在网络安全领域中,当服务器遭受大规模DDoS攻击或其他恶意流量冲击时,为了保护服务的稳定性和其他正常用户的使用体验,往往会采取一种紧急防护手段——将服务器置于黑洞状态。所谓黑洞状态,即网络服务商暂时屏蔽掉对服务器的…

“中国汉字”的英语表达|柯桥考级英语生活英语商务口语培训

汉字,又称中文字、中国字、方块字。汉字是表意文字,一个汉字通常表示汉语里的一个词或一个语素,这就形成了音、形、义统一的特点。 我们通常用“Chinese character”表示“汉字”而不用“Chinese word”. 🔴 例句: C…

QT:信号和槽

文章目录 信号和槽connect函数槽自定义槽第一种第二种 信号和槽 这里的信号和Linux的信号一样吗? 答案是差不多,但是也有一定的区别,而且也是两个不同的概念 信号有三个概念,一个是信号源,这个信号是由谁发送的&…

信息管理与信息系统就业方向及前景分析

信息管理与信息系统(IMIS)专业的就业方向十分广泛,包含计算机方向、企业信息化管理、数据处理和数据分析等,随着大数据、云计算、人工智能、物联网等技术的兴起,对能够处理复杂信息系统的专业人才需求激增,信息管理与信息系统就业…

Storm 技术揭秘:掌握实时大数据处理的终极神器!

Storm 是一个开源的分布式实时计算系统,由 Twitter 公司开发并贡献给 Apache 基金会。它可以处理大量的数据流,进行实时的数据挖掘、数据分析和数据可视化等任务。Storm 具有高容错性、可扩展性和低延迟的特点,适用于需要快速响应的场景&…

15、ESP32 Wifi

ESP32 的 WIFI 功能是模块内置的&#xff0c;通过 ESP32 的基础库调用一些函数就可以轻松使用它。 Wifi STA 模式&#xff1a; 让 ESP32 连接附近 WIFI&#xff0c;可以上网访问数据。 // 代码显示搜索连接附近指定的 WIFI // 通过 pin 按键可断开连接#include <WiFi.h>…

纯血鸿蒙APP实战开发——主页瀑布流实现

介绍 本示例介绍使用ArkUIWaterFlow组件和LazyForEach实现瀑布流场景。该场景多用于购物、资讯类应用。 效果图预览 使用说明 加载完成后显示整个列表&#xff0c;超过一屏时可以上下滑动。 实现思路 创建WaterFlowDataSource类&#xff0c;实现IDataSource接口的对象&…

JAVA面试之MQ

如何保证消息的可靠传输&#xff1f;如果消息丢了怎么办 数据的丢失问题&#xff0c;可能出现在生产者、MQ、消费者中。 &#xff08;1&#xff09;生产者发送消息时丢失&#xff1a; ①生产者发送消息时连接MQ失败 ②生产者发送消息到达MQ后未找到Exchange(交换机) ③生产者发…

第一次用ssh登录树莓派or linux服务器出现Permission denied (publickey)

authenticity of host ) cant be established ssh userip Permission denied (publickey) 解决办法&#xff1a; 第一步&#xff1a; PasswordAuthentication yes 第二步&#xff1a; service sshd restart 这两步一步都不能少 注意&#xff01;

如何搭建本地的 NPM 私有仓库 Nexus

NPM 本地私有仓库&#xff0c;是在本地搭建NPM私有仓库&#xff0c;对公司级别的组件库进行管理。在日常开发中&#xff0c;经常会遇到抽象公共组件的场景&#xff0c;在项目内部进行公用。新的项目开始时&#xff0c;也会拷贝一份创建一个新的项目&#xff0c;这样做不易于管理…

k8s部署maven项目

failed to verify certificate: x509: certificate signed by unknown authority 今天在执行kubectl get nodes的时候报的证书验证问题&#xff0c;看了一圈首次搭建k8s的都是高频出现的问题。 couldn’t get current server API group list: Get “https://kubernetes.docker…

虚拟机网络桥接模式无法通信,获取到的ip为169.254.X.X

原因&#xff1a;VMware自动选择的网卡可能不对 解决&#xff1a;编辑-虚拟网络编辑器-更改桥接模式-选择宿主机物理网卡&#xff0c;断开虚拟机网络连接后重新连接即可

能源监控新方案:IEC104转MQTT网关在新能源发电中的应用

需求背景 近些年&#xff0c;我国新能源产业快速发展&#xff0c;光伏、风电等新能源项目高速增长&#xff0c;新能源发电已经成为国家能源结构的重要组成部分。 打造数字化、智能化、信息化的电力物联网系统&#xff0c;实现光伏风电等新能源发电站的远程监控、远程维护是新能…

每日一题-贪心算法

目录 前言 买入股票的最佳时机(1) 买入股票的最好时机(2) 前言 当你踏上贪心算法的旅程&#xff0c;仿佛置身于一场智慧的盛宴&#xff0c;每一步都是对问题解决方案的审慎选择&#xff0c;每一次决策都是对最优解的向往。贪心算法以其简洁高效的特性&#xff0c;被广泛运用于…

【golang学习之旅】Go的 switch 分支语句

系列文章 【golang学习之旅】报错&#xff1a;a declared but not used 【golang学习之旅】Go 的基本数据类型 【golang学习之旅】Go 的循环结构 【golang学习之旅】Go里面 if 条件判断语句 目录 系列文章switch 分支fallthrough 关键字无条件 switch switch 分支 有些时候需…