AArch64 内存管理

        本文是对arm developer网站《Learn the architecture - AArch64 memory management Guide》的学习笔记(Documentation – Arm Developer)

一、背景概述

        本文介绍了AArch64中的内存转换,这是内存管理的关键,它解释了虚拟地址如何转换为物理地址、转换表的格式以及软件如何管理TLB。

1. 什么是内存管理

        内存管理描述了如何控制对系统内存的访问。操作系统或应用程序访问内存时,硬件都会执行内存管理。内存管理是一种向应用程序动态分配内存区域的方法。

2. 为什么需要内存管理

        AP旨在运行rich os(如Linux),需要支持虚拟内存系统,AP上运行的软件只能看到虚拟地址,AP将虚拟内存转换为物理地址,物理地址最终指向内存中的实际物理位置。

3. 虚拟地址和物理地址

        使用虚拟地址的好处是它允许管理软件(例如OS)控制呈现给软件的内存视图,OS可以控制哪些内存是可见的、该内存可见的虚拟地址以及允许对该内存进行哪些访问。这允许操作系统对应用程序进行沙箱处理(对另一应用程序隐藏一个应用程序的资源)并提供对底层硬件的抽象。】

        用虚拟地址的另一个好处是操作系统可以将多个碎片物理内存区域作为单个连续的虚拟地址空间呈现给应用程序。

        虚拟地址也有利于软件开发人员,软件开发人员使用虚拟地址,无需关心物理内存。实际上,每个应用程序都可以使用自己的一组虚拟地址,这些地址将映射到物理系统中的不同位置。当操作系统在不同的应用程序之间切换时,需要重新组织物理地址和虚拟地址的映射关系。

        虚拟地址通过映射转换为物理地址。虚拟地址和物理地址之间的映射存储在转换表(有时称为页表)中,如下图所示:

        页表位于内存中,并由软件(通常是OS或hypervisor)管理, 页表不是静态的,并且随着软件需求的变化而刷新。

4. 地址空间

4.1 虚拟地址空间

        AArch64有多个独立的虚拟地址空间,如下(Armv8-A中的地址空间):

        NS.EL0:非安的EL0,在Linux中对应用户态虚拟地址空间,页表基址寄存器TTBR0_EL1

        NS.EL1:非安的EL1,在Linux中对应内核态虚拟地址空间,页表基址寄存器TTBR1_EL1

        NS.EL2:非安的EL2,EL2是可选的

        EL3:EL3也是可选的

        每个虚拟地址空间都是独立的,并且有自己的配置和页表。此外,还有Secure EL0、Secure EL1和Secure EL2的虚拟地址空间,图中没有显示。(Armv8.4-A 中添加了对 Secure EL2 的支持。)

        由于存在多个虚拟地址空间,因此指定地址位于哪个地址空间非常重要。例如,NS.EL2:0x8000指的是非安全 EL2 虚拟地址空间中的地址0x8000

        上图还显示了NS.EL0和NS.EL1中的虚拟地址经过了两步地址转换(2-stage),表示这些表支持虚拟化,虚拟机VM内看到的物理内存还需要经过stage-2的页表才能转换为实际的物理内存。;

        Armv9-A支持上述 Armv8-A 的所有虚拟地址空间。 Armv9-A 引入了可选的领域管理扩展 (RME)。如果实现了RME ,还存在其他转换机制

  • Realm EL1和EL0
  • Realm EL2和EL0
  • Realm EL2

        在虚拟化中,我们将OS控制的一组转换称为stage-1。stage-1页表将虚拟地址转换为中间物理地址 (IPA)。在stage-1,操作系统认为 IPA 是物理地址空间。然而,虚拟机管理程序控制stage-2转换,第二组转换将 IPA 转换为物理地址。下图显示了两组翻译的工作原理:

4.2 物理地址空间

        除了多个虚拟地址空间之外,AArch64 还具有多个物理地址空间(PAS):

  • 非安全 PAS0
  • 安全PAS
  • Realm PAS(仅限 Armv9-A)
  • root PAS(仅限 Armv9-A)

        虚拟地址可以映射到什么物理地址空间取决于处理器当前的安全状态。下表显示了安全状态及其相应的虚拟地址映射

  • 非安全状态:虚拟地址只能映射到非安全物理地址。
  • 安全状态:虚拟地址可以映射到安全或非安全物理地址。
  • Realm状态:虚拟地址可以映射到Realm或非安全物理地址
  • root 状态:虚拟地址可以映射到任意物理地址空间。

note:这些访问权限由页表控制(//todo)

4.3 地址空间大小

        AArch64是64位架构,但这并不意味着所有地址都是64位的。

4.3.1 虚拟地址空间的大小

        虚拟地址以 64 位格式存储。因此,加载指令 (LDR) 和存储指令 (STR) 中的地址始终在通用寄存器中指定。然而,并非通用寄存器中的所有地址都是有效的。

        下图显示了 AArch64 中虚拟地址空间的布局:

        EL0/EL1虚拟地址空间有两个区域:内核空间和应用程序空间。这两个区域显示在图的左侧,内核空间位于顶部,应用程序空间(标记为“用户空间”)位于地址空间的底部。内核空间和用户空间具有单独的页表,这意味着它们的映射可以保持分离。 

        在地址空间的底部有一个区域用于所有其他异常级别。该区域显示在图的右侧。

        如果将 HCR_EL2.E2H 设置为 1,则会host os在 EL2 中运行,host os的应用程序在 EL0 中运行的配置。在这种情况下,EL2也有上部和下部区域。(即type2的虚拟化)

        地址空间的每个区域的大小最多为 52 位。然而,每个区域都可以独立地缩小到更小的尺寸。 TCR_ELx 寄存器中的 TnSZ 字段控制虚拟地址空间的大小。例如,下图显示 TCR_EL1 控制 EL0/EL1 虚拟地址空间:

        

        虚拟地址空间大小为:

virtual address size in bytes = 2^(64-TCR_ELx.TnSZ)

        因此,如果TCR_ELx.T1SZ 设置为32,则EL0/EL1虚拟地址空间中内核区域的大小为2^32字节(0xFFFF_FFFF_0000_0000至0xFFFF_FFFF_FFFF_FFFF)。任何超出配置范围的地址在被访问时都会生成异常作为转换错误。这种配置的优点是我们只需要描述我们想要使用的地址空间,这节省了时间和空间。例如,假设操作系统内核需要 1GB 地址空间(30 位地址大小)作为其内核空间。如果操作系统将 T1SZ 设置为 34,则仅创建描述 1GB 的转换表条目,即 64 - 34 = 30。

        所有 Armv8-A 实现都支持 48 位虚拟地址。对 52 位虚拟地址的支持是可选的,并由 ID_AA64MMFR2_EL1 报告。

4.3.2 物理地址空间的大小

        物理地址的大小由实现定义,最大为 52 位。 ID_AA64MMFR0_EL1 寄存器报告处理器实现的大小。对于 Arm Cortex-A 处理器,通常为 40 位或 44 位。

        在 Armv8.0-A 中,物理地址的最大大小为 48 位。在 Armv8.2-A 中这已扩展到 52 位

4.3.3 IPA地址空间的大小

         如果在转换表条目中指定的输出地址大于实现的最大值,MMU)将产生地址大小错误异常。

        IPA空间的大小可以与虚拟地址空间相同的方式配置。 VTCR_EL2.T0SZ 控制大小。可以配置的最大大小与处理器支持的物理地址大小相同。这意味着您无法配置比支持的物理地址空间更大的 IPA 空间。

4.4 ASID-地址空间标识符

        许多现代操作系统的应用程序都在同一地址空间运行,但不同的应用程序有自己的虚拟地址空间。这意味着 VA 0x8000的地址转换取决于当前正在运行的应用程序。    

        理想情况下,我们希望不同应用程序的翻译能够在翻译后备缓冲区 (TLB) 中共存,以防止 TLB 在上下文切换时失效。但是处理器怎么知道要使用哪个版本的 VA 0x8000转换呢?在 AArch64 中,答案是地址空间标识符 (ASID)     

        对于 EL0/EL1 虚拟地址空间,可以使用转换表条目的属性字段中的 nG 位将转换标记为全局 (G) 或非全局 (nG)。例如,内核映射是全局翻译,应用程序映射是非全局翻译。全局翻译适用于当前正在运行的任意应用程序。非全局翻译仅适用于特定应用程序。

        非全局映射在 TLB 中用 ASID 进行标记。在 TLB 查找中,TLB 条目中的 ASID 与当前选择的 ASID 进行比较。如果它们不匹配,则不使用 TLB 条目。下图显示了内核空间中没有 ASID 标记的全局映射和用户空间中带有 ASID 标记的非全局映射:

        该图显示,多个应用程序的 TLB 条目可以在缓存中共存,ASID 决定使用哪个条目。 

        ASID 存储在两个 TTBRn_EL1 寄存器之一中。通常TTBR0_EL1用于用户空间。因此,更新TTBRn_EL1寄存器可以更改 ASID 及其指向的转换表。

        HCR_EL2.E2H为1时(type2的虚拟化),ASID标记也可以在EL2中使用

4.5 VMID-虚拟机标识符

        EL0/EL1 转换还可以使用虚拟机标识符 (VMID) 进行标记。 VMID 允许来自不同 VM 的转换在缓存中共存。这类似于 ASID 用于来自不同应用程序的翻译的方式。实际上,这意味着某些翻译将同时标记有 VMID 和 ASID,并且两者都必须与要使用的 TLB 条目匹配。

        当安全状态支持虚拟化时,EL0/EL1 转换始终标记有 VMID,即使未启用stage-2转换。这意味着,如果您正在编写初始化代码并且不使用hypervisor,则在设置stage-1 MMU 之前设置已知的 VMID 值非常重要。

4.6 Common not Private

        如果一个系统包括多个PE,在一个PE上使用的ASIDs和VMIDs在其他PE上是否有相同的意义?对于 Armv8.0-A,答案是它们不必表示相同的意思。不要求软件在多个PE上以相同的方式使用给定的 ASID。例如,ASID 5 可能由一个处理器上的计算器使用,并由另一处理器上的 Web 浏览器使用。这意味着由一个处理器创建的 TLB 条目不能被另一处理器使用。

        实际上,软件不太可能在不同的PE上以不同的方式使用 ASID。对于软件来说,更常见的是在给定系统中的所有PE上以相同的方式使用 ASID 和 VMID。因此,Armv8.2-A 在转换表基址寄存器 (TTBR) 中引入了 Common not Private (CnP) 位。当 CnP 位被设置时,软件承诺在所有处理器上以相同的方式使用 ASID 和 VMID,这允许一个处理器创建的 TLB 条目可以由另一个处理器使用。

        note:处理单元Processing Element (PE),PE是任何实现 Arm 架构的处理单元。这一点在这里很重要,因为微架构方面的原因导致处理器之间共享 TLB 会很困难。但在多线程处理器中,每个硬件线程都是一个 PE,因此更需要共享 TLB 条目。

5. MMU(内存管理单元)

        内存管理单元 (MMU) 负责将软件使用的虚拟地址转换为内存系统中使用的物理地址。

        MMU 包含以下内容:

  • The table walk unit:从内存中读取转换表的逻辑
  • Translation Lookaside Buffers (TLBs):缓存最近使用的翻译

        软件分配的所有内存地址都是虚拟的。这些内存地址被传递到 MMU,MMU 检查 TLB 中是否有最近使用的缓存翻译。如果 MMU 没有找到最近缓存的翻译,表遍历单元会从内存中读取相应的表条目,如下所示:        

        在进行内存访问之前,必须将虚拟地址转换为物理地址(因为我们必须知道正在访问哪个物理内存位置)。这种转换需求也适用于缓存数据(cached data),因为在 Armv6 及更高版本的处理器上,数据缓存使用物理地址(物理标记的地址)存储数据。因此,在完成高速缓存查找之前必须转换地址。 

5.1 Table entry(表项)

        转换表的工作原理是将虚拟地址空间划分为大小相等的块,并为每个块提供表中的一个条目(表项)

        表中的条目 0 提供块 0 的映射,条目 1 提供块 1 的映射,依此类推。每个条目包含相应物理内存块的地址以及访问物理地址时要使用的属性。

        

5.2 查表

        翻译时会进行查表,当转换发生时,软件发出的虚拟地址被分成两部分,如下图所示:

        上图是单级查找表,高位在图中标记为“which entry”,低位被标记为"offset in block"。

5.3 多级页表

        在单级查找中,虚拟地址空间被分割成大小相等的块。在实践中,使用多级页表。一级表将虚拟地址空间划分为大块,表中的每个表项指向大小相同的物理内存块,也可以指向将该块细分为更小的块的另一个表。下图是三个级别的多级页表示例。

        

        在 Armv8-A 中,最大级别数为 4,级别编号为 0 到 3。这种多级方法允许描述较大的块和较小的块。大块和小块的特点如下: 

  • 大块比小块需要更少的读取级别来转换。另外,大块在 TLB 中缓存的效率更高
  • 小块使软件可以对内存分配进行细粒度控制。然而,小块在 TLB 中缓存的效率较低。缓存效率较低,因为小块需要多次读取各个级别才能进行转换。

当处理器开始查表时,它不知道翻译的大小。处理器通过执行查表来计算出正在转换的块的大小。

5.4 控制地址转换表格式

        在这里我们可以看到转换表条目允许的不同格式:

        

        每个表项都是 64 位,底部两个bit位确定表项的类型。请注意,某些table entry仅在特定级别有效。table的最大级别数是四级,这就是为什么没有level3(或第四级)表的Table Descriptor的原因(即level 3不可能再指向下级表项)。同样地,第0级也没有块描述符或页描述符。因为第0级 entry覆盖了很大的虚拟地址空间区域,因此在level0允许块是没有意义的,即level0永远都会指向下级表。

5.5 转换粒度

        转换粒度是可以描述的最小的内存块。AArch64 支持三种不同的粒度大小:4KB、16KB 和 64KB。处理器支持的粒度是自定义的,由 ID_AA64MMFR0_EL1 保存。所有Arm Cortex-A处理器都支持4KB和64KB。选择的粒度是最高level table中描述的大小。

        一个处理器所支持的粒度大小是ID_AA64MMFR0_EL1定义的,所有Arm Cortex-A处理器都支持4KB和64KB。选择的颗粒是可以在最新级别表中描述的最小块。也可以描述更大的块。此表显示了基于所选粒度的每个级别表的不同块的尺寸:

        在推出 Armv9.2-A 和 Armv8.7-A 之前,使用 52 位地址存在限制。当选择的颗粒为4KB或16KB时,最大虚拟地址区域大小为48位。同样,输出物理地址限制为 48 位。只有当使用64KB颗粒时才能使用完整的52位。 

5.6 地址转换的起始级别

        虚拟地址空间的粒度和大小共同控制地址转换的起始级别。上表总结了每个级别表中每个粒度的块大小(单个entry覆盖的虚拟地址范围的大小)。从块的大小,你可以算出虚拟地址的哪些位是用来索引每一级表的。

        我们以4KB的粒度为例。这张图显示了用于索引4KB粒度的 不同级别表的索引。

        由于是4K的页表,0:11的低12位是4K的块内偏移,4K的页表一共有512个表项(每个表项8个字节),所以需要9个bit来表示每一级页表的索引。

        如图所示,将TCR_EL1.T0SZ设置为32,以地址为单位的虚拟地址空间的大小计算方式如下:64 - T0SZ = 32 bit

        从之前的4KB配置的粒度图中可以看出,level0是47:39位索引的。这些在32位地址空间是不存在的。因此,地址翻译是从level1开始的。接着,假设设置T0SZ为34:64 - T0SZ = 30, 这一次,不存在level0 和level1的索引。因此,该配置的转译起始级别是level2。

        当虚拟地址空间的大小减少时,您需要更少级别的表来描述它。这些示例基于使用 4KB 粒度。当使用 16KB 和 64KB 颗粒时,同样的原理也适用,但地址位会发生变化

5.7 控制地址转换的寄存器
  • SCTLR_ELx

        M:使能MMU

        C:使能Dcache

  • TTBR0_ELx and TTBR1_ELx

         BADDR:转译表物理地址/中间物理地址的起点

        ASID:非全局转译的标识符

  • TCR_ELx

        PS/IPS:PA 或 IPA 空间的大小

        TnSZ:转译表能表示的地址空间的大小

        TGn:粒度大小

        SH/IRGN/ORGN:缓存能力共享能力的使能

        TBIn:禁止搜索table中的某一行

  • MAIR_ELx

        Attr:statge1 的类型和缓存能力控制

5.8 禁用MMU

        MMU被禁用时,所有地址都是平行映射,即输入和输出地址相同

5.9 维护TLB

        Translation Lookaside Buffers (TLB) 缓存最近使用的转译项。此缓存允许后续查找重复使用转译,而无需重新读取table。

                如果要更改转换表entry或控制entry的解释方式,则需要使 TLB 中受影响的entry无效。如果不使这些entry无效,则处理器可能会继续使用旧的转译。

        处理器不允许导致以下任何故障的翻译缓存到 TLB:

  • 翻译错误(未映射的地址)
  • 地址大小错误(超出地址范围)
  • 非法访问

因此,在第一次映射地址时,你不需要让TLB 无效。然而,如果要做以下操作,需要让TLB失效:

  • Unmap an address:将有效的地址标记为无效
  • 改变映射关系:将地址权限从只读改为读写。
  • 改变table 的转译方式:修改粒度大小时,table的转译方式也会改变。
5.10 操作TLB的方式

        TLBI 指令用于使 TLB 中的条目无效。该指令的语法为:

TLBI < type >< level >{IS|OS} {, < xt >}

< type >:指定无效的entries

        All - 所有entries

        VA - Entry matching VA and ASID in Xt

        VAA - Entry matching VA in Xt, for any ASID

        ASID - Any entry matching the ASID in Xt

< level >: 操作哪一个地址空间

        E1 = EL0/1 virtual address space

        E2 = EL2 virtual address space

        E3 = EL3 virtual address space

 < IS|OS >内部共享还是外部共享

< Xt >:操作那个地址或者ASID

        例如,考虑一个正在更新其内核转换表中的条目的操作系统 (OS)。典型的 TLB 无效序列如下所示:        

STR  X1, [X5]        // Write to translation table entry
DSB  ISH             // Barrier instructions - not covered in this guide
TLBI VAAE1IS  , X0   // Invalidate VA specified by X0, in EL0/1
                     // virtual address space for all ASIDs
DSB  ISH             // Barrier instructions - not covered in this guide
ISB                  // Synchronize context on this processor
5.11 地址转换说明

        地址转换指令(AT)可以查询特定地址的转换。地址翻译的结果,属性会写入物理寄存器PAR_EL1。

        AT指令的语法具有优先级。例如,EL2指令可以查询EL0/EL1的翻译表,但是EL1指令不能查询EL2的。

6. check

Q:地址翻译中,statge和level有什么区别?

A:statge 指的是把输入地址转换为输出地址的过程。对于stage1,就是从VA到IPA的过程。stage2 从IPA到PA的过程。level指的是翻译给定阶段的table,将一个大块划分为小块的过程。

Q:物理地址最大是多少?

A:物理地址大小由IMPLEMENTATION DEFINED定义,在ARMV8.2-A后为52位。

Q:虚拟地址大小由哪些寄存器控制?

A:stage2的TCR_ELx.TnSZ, or VTCR_EL2.T0SZ

Q:翻译粒度是什么?支持的大小是多少?

A:翻译粒度指的是内存可以描述的最小的块。支持4KB, 16KB, and 64KB.

Q:TLBI ALLE3 作用是什么?

A:EL3虚拟地址中使所有的TLB entries无效。

Q:发生翻译错误时的翻译表项能缓存在TLB中吗?

A:不能

Q:当MMU关闭时,地址是如何映射的?

A:平行映射,即输入地址和输出地址相同。

Q:什么是ASID?什么时候TLB entry会包含ASID?

A:ASID是地址空间标识符,它标识了翻译与那个应用相关联。非全局映射(nG=1)在在TLB中被标记为一个ASID。

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

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

相关文章

成语:势如破竹、迎刃而解;明以前唯一同时入选文庙、武庙的牛人

千古流芳、身后能够进入文庙或武庙&#xff0c;是古人最高的荣誉&#xff0c;也是读书人和武将终极的追求&#xff0c;所谓的青史留名&#xff0c;享受万代祭祀、千秋敬仰&#xff0c;甚至都可以称之为圣人&#xff0c;但历史上&#xff0c;却有两人文武兼备、同时入选了文庙与…

单调栈-java

本次主要通过数组模拟单调栈来解决问题。 目录 一、单调栈☀ 二、算法思路☀ 1.暴力做法&#x1f319; 2.优化做法&#x1f319; 3.单调递增栈和单调递减栈&#x1f319; 三、代码如下☀ 1.代码如下&#xff08;示例&#xff09;&#xff1a;&#x1f319; 2.读入数据&a…

学习记录:AUTOSAR R20-11的阅读记录(一)【Foundation(FO)】

一、OverView 1、AUTOSAR R20-11文档下载 官网下载&#xff1a;AUTOSAR 打包文档地址&#xff1a;AUTOSAR R20-11 2、文档组说明 AUTOSAR定义了三个文档组&#xff1a;ClassicPlatform(CP)、Adaptive Platform(AP)和Foundation(FO)&#xff0c;基于CP和AP的ECU基于共同标准F…

php基础知识快速入门

一、PHP基本知识 1、php介绍&#xff1a; php是一种创建动态交互性的强有力的服务器脚本语言&#xff0c;PHP是开源免费的&#xff0c;并且使用广泛。PHP是解释性语言&#xff0c;按顺序从上往下执行&#xff0c;无需编译&#xff0c;直接运行。PHP脚本在服务器上运行。 2、ph…

【算法】滑动窗口——无重复字符的最长子串

本篇博客是一篇滑动窗口算法练习题——无重复字符的最长子串的思路详解&#xff0c;从最开始的暴力解法&#xff0c;优化以及怎么想到滑动窗口这种算法的一个详细思路过程&#xff0c;有需要借鉴即可。 目录 1.题目解读2.暴力求解3.暴力求解的优化4.题解代码示例 1.题目解读 题…

超详细——集成学习——Adaboost——笔记

资料参考 1.【集成学习】boosting与bagging_哔哩哔哩_bilibili 集成学习——boosting与bagging 强学习器&#xff1a;效果好&#xff0c;模型复杂 弱学习器&#xff1a;效果不是很好&#xff0c;模型简单 优点 集成学习通过将多个学习器进行结合&#xff0c;常可获得比单一…

无经验计科应届生前端面试遇到的问题整理

js数据类型有几种&#xff0c;分别是 原始数据类型&#xff08;Primitive data types&#xff09;: 字符串&#xff08;String&#xff09;: 用于表示文本数据&#xff0c;使用单引号&#xff08;‘’&#xff09;或双引号&#xff08;“”&#xff09;括起来。 数字&#xff…

27-代码随想录三数之和

15. 三数之和 中等 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重…

C++ 如何进阶?

一、C基础&#xff08;3个月&#xff09; 1、面向对象的三大特性&#xff1a;封装、继承、多态 2、类的访问权限&#xff1a;private、protected、public 3、类的构造函数、析构函数、赋值函数、拷贝函数 4、移动构造函数与接贝构造函数对比 5、深接贝与浅贝的区别 6、空…

创新指南|组织健康仍然是企业创新长期绩效的关键

麦肯锡关于组织健康的最新调查结果表明&#xff0c;它仍然是当今全球市场中价值创造的最佳预测者和竞争优势的可持续来源。在本文中&#xff0c;我们将探讨最新的 OHI 结果&#xff0c;并重点介绍该指数揭示的有关领导力、数据和技术以及人才管理的一些更引人注目的见解。我们还…

数据仓库基础理论(学习笔记)

数据仓库基础理论 1.数据仓库概念 2.数据仓库为何而来 3.数据仓库主要特征 4.OLTP、OLAP系统 5.数据仓库与数据库的区别 6.数据仓库与数据集市的区别 7.数据仓库分层架构 7.1为什么要分层&#xff1f; 8.ETL、ELT

【前端】创建跳动字符效果的前端技术实现

创建跳动字符效果的前端技术实现 在前端开发中&#xff0c;动态视效能够显著增强用户体验。本文介绍一种实现字符跳动效果的技术方案&#xff0c;通过简单的HTML、CSS和JavaScript代码&#xff0c;你可以为网页文本添加生动的交互动画。这种效果可以用于吸引用户注意、增强品牌…

C语言—控制语句

控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1&#xff1b; } else { 语句块2&#xff1b; } 执行顺序&#xff1a; 如果表达式判断成立&#xff08;即表达式为真&#xff09;&#xff0c;则执行语句块…

华为先进芯片麒麟9010效能再升级,挑战新高度 | 百能云芯

根据最新的彭博资讯报道&#xff0c;华为再次引领了智能手机行业的先进技术&#xff0c;其最新发布的Pura 70系列智能手机搭载了由中芯国际生产的麒麟9010高阶处理器。这一消息再次证明了华为在芯片设计和生产领域的持续创新能力&#xff0c;并且表明华为对于提升智能手机性能和…

什么是虚拟货币?

随着科技的进步&#xff0c;虚拟货币逐渐进入公众视野&#xff0c;其影响深远且复杂。本文将从专业角度分析虚拟货币的发展现状、未来趋势&#xff0c;以及面临的挑战&#xff0c;并尝试提出一些思考。 一、虚拟货币的定义与现状 虚拟货币是一种基于区块链技术的数字资产&…

从固定到可变:利用Deformable Attention提升模型能力

1. 引言 本文将深入探讨注意力机制的内部细节&#xff0c;这是了解机器如何选择和处理信息的基础。但这还不是全部&#xff0c;我们还将探讨可变形注意力的创新理念&#xff0c;这是一种将适应性放在首位的动态方法。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 注…

Dockerfile创建Docker镜像

Dockerfile DOCKER镜像的组成 Docker 镜像的构建和使用是基于 UnionFS&#xff08;联合文件系统&#xff09;的原理。UnionFS 允许将多个目录挂载到一个虚拟文件系统下&#xff0c;并且可以对这些目录进行修改&#xff0c;这些修改会以一次提交的形式叠加在已有的文件系统层上…

CTF-WEB(MISC)

安全攻防知识——CTF之MISC - 知乎 CTF之MISC杂项从入门到放弃_ctf杂项 你的名字-CSDN博客 CTF MICS笔记总结_archpr 掩码攻击-CSDN博客 一、图片隐写 CTF杂项---文件类型识别、分离、合并、隐写_ctf图片分离-CSDN博客 EXIF&#xff08;Exchangeable Image File&#xff09;是…

笔记本电脑怎么多选删除文件?误删除文件怎么办

在日常使用笔记本电脑中&#xff0c;我们可能会遇到需要删除大量文件的情况&#xff0c;例如清理临时文件、整理文档或卸载不再需要的程序。手动一个一个地删除不仅效率低下&#xff0c;还可能遗漏某些文件。那么&#xff0c;如何在笔记本电脑上高效地进行多选删除操作呢&#…

Case中default的综合结果

在使用case语句时&#xff0c;不完备的case语句会导致Vivado综合时推断出锁存器。下面通过实例来详细看看各种情况下的综合结果&#xff1a; 1.完备的case语句 下述的verilog对应的电路结构是一个8选一的多路复用器&#xff1a; module case_test(input [2:0]sel,input data…
最新文章