当前位置: 首页 > news >正文

计算机系统结构 第二章 :缓存优化

零-1:复习cache的基础知识:

一、映像方式

直接映射

原理:主存被分成若干区,每个区大小与 Cache 相同,区内再分块,主存每个区中块的大小和 Cache 中块大小相等,且每个区包含的块数也与 Cache 中块数相等。主存中任意一个块只能映射到 Cache 中唯一指定的块(相同块号位置) 。主存地址分为区号、块号和块内地址三部分,Cache 地址则分为块号和块内地址。例如,假设主存容量大,有多个区,每个区有若干块,而 Cache 只有一个区,那么主存某区的第 i 块只能对应到 Cache 的第 i 块。

特点:地址变换简单、速度快,可直接由主存地址提取出 Cache 地址。但不灵活,块冲突率较高,当不同区的相同块号的主存块都要调入 Cache 时,会发生冲突,导致 Cache 空间得不到充分利用 。

全相联映射

原理:主存中任何一个块都可以映像装入到 Cache 中的任何一个块的位置上。主存地址和 Cache 地址都分为块号和块内地址两部分。Cache 的块内地址直接取自主存地址的块内地址段,主存块号和 Cache 块号不同,Cache 块号需根据主存块号从块表中查找 。比如主存的任意一块,可放入 Cache 的任意一块位置。

特点:灵活性高,块冲突率低,只有当 Cache 中的块全部装满后才会出现冲突,Cache 利用率高。但地址变换机构复杂,地址变换时需把请求地址同 Cache 中所有地址进行比较来确认,速度慢,成本高 。

组相联映射

原理:是直接映射和全相联映射的折中。主存按 Cache 容量分区,每个区再分为若干组,每组包含若干块,Cache 也进行同样的分组和分块,且主存中一个组内的块数与 Cache 中一个组内的块数相等。组间采用直接映射方式,组内采用全相联映射方式 。即主存某组的块可映射到 Cache 对应组的任意一块中。主存地址包括区号、组号、主存块号和块内地址,Cache 地址包括组号、组内块号和块内地址 。

特点:兼顾了直接映射和全相联映射的优点,地址变换复杂度和块冲突率介于两者之间,是实际中常用的映像方式 。当组的容量为 1 时,就是直接映射;当组的容量等于整个 Cache 的容量时,就是全相联映射 。

二、替换算法

LRU 算法(Least Recently Used)

原理:认为一段时间内最少使用的块,在未来一段时间内也最可能不被使用。当 Cache 已满,需要调入新块时,会淘汰最后一次访问时间最久远的那个块 。例如,记录每个块的最后访问时间,每次有新访问操作时更新对应块的时间,替换时选择时间最久的块淘汰。

特点:命中率相对较高,比较符合程序访问的局部性原理(程序往往会在一段时间内集中访问某些数据),但实现相对复杂,需要额外的硬件或软件机制来记录块的访问时间 。

FIFO 算法(First In First Out )

原理:遵循先入先出原则,当 Cache 被填满,需要替换块时,淘汰最早进入 Cache 的那个块 。就像排队一样,先进入 Cache 的块先被淘汰。

特点:实现简单,只需维护一个队列记录块的进入顺序即可。但缺点是可能会把经常使用但较早进入 Cache 的块淘汰掉,导致命中率不高 。

随机替换算法

原理:当 Cache 需要替换块时,直接随机选择一个块进行淘汰 。

特点:实现非常简单,不需要记录块的访问历史等信息。但命中率较低,因为随机选择不一定能淘汰掉最不常用的块,缺乏对程序访问规律的利用 。

三、写策略

写命中策略

写直达法(全写法,Write Through )

原理:当 CPU 对 Cache 写命中时,必须把数据同时写入 Cache 和主存。一般会使用写缓冲(write buffer)来暂时存储写操作数据,以减少对主存的访问次数 。例如,CPU 要修改 Cache 中某块的数据,在修改 Cache 的同时,将数据也写入主存,若有写缓冲,先写入缓冲,再由缓冲写入主存。

特点:能保证数据的一致性,即 Cache 和主存中的数据时刻保持相同。但每次写操作都要访问主存,会增加访存次数,可能影响系统性能 。

写回法(Write Back )

原理:当 CPU 对 Cache 写命中时,只修改 Cache 的内容,不立即写入主存。只有当此 Cache 块被替换出时才写回主存 。比如 CPU 修改 Cache 中的数据块后,该块继续留在 Cache 中,直到被其他块替换时,才将修改后的数据写回主存。

特点:减少了访存次数,提高了写操作的性能。但存在数据不一致的隐患,在 Cache 块写回主存之前,Cache 和主存中的数据是不一致的 。

写不命中策略

写分配法(Write Allocate )

原理:当 CPU 对 Cache 写不命中时,先从主存中读取相应的块到 Cache 中,然后在这个 Cache 块中进行写入操作 。这是利用了数据的空间局部性原理,即如果 CPU 访问了某个主存块中的数据,那么它很可能在不久的将来再次访问该块或其附近的数据 。

特点:适用于数据存在空间局部性的场景,预先将可能再次被访问的数据块调入 Cache,可以提高后续访问的速度。但会增加 Cache 的写入流量和复杂性 。

写不分配法(Not Write Allocate )

原理:当 CPU 对 Cache 写不命中时,只写入主存,不调入 Cache 。

特点:简化了 Cache 的写操作过程,减少了 Cache 的写入流量。然而,由于写操作没有利用 Cache 的加速效果,可能会导致后续对该数据块的读操作性能下降,因为读操作无法从 Cache 中快速获取数据 。

零-2:复习存储系统的基本知识:


一、存储系统三个相互矛盾的指标

1. 速度

速度指的是存储设备读写数据的快慢程度,通常用访问时间来衡量。访问时间越短,存储设备的速度就越快。例如,寄存器的访问时间通常在几个时钟周期内,能与 CPU 的运算速度相匹配,可快速为 CPU 提供数据;而磁盘的访问时间则达到毫秒级别,速度相对寄存器和内存来说非常慢。

2. 容量

容量是指存储设备能够存储的数据量大小,一般以字节(Byte)为单位,常见的有 KB、MB、GB、TB 等。不同的存储设备容量差异巨大,像寄存器的容量通常只有几十个字节到几百个字节;而磁盘的容量可以达到数 TB。

3. 价格

价格体现了存储设备的成本,通常用每单位容量的价格来衡量。一般来说,速度越快的存储设备,每单位容量的价格越高。例如,高速的 SRAM(静态随机存取存储器)每 GB 的价格远高于低速的磁盘。

矛盾关系

这三个指标相互制约、相互矛盾。要提高存储系统的速度,往往需要采用更先进的技术和材料,这会导致成本增加,价格上升,同时也难以实现大容量。例如,要构建大容量的寄存器存储系统,成本会高得难以承受。若要追求大容量,通常会选择成本较低的存储技术,但其速度会较慢。而若要降低价格,就可能需要牺牲速度和容量。

二、多级存储层次结构

1. 局部性原理

空间局部性:

程序即将用到的信息很可能与现在用到的信息相邻。这是因为程序在执行过程中,通常会顺序访问代码和数据,或者对数组等连续存储的数据结构进行操作。例如,在遍历数组时,会依次访问数组中的相邻元素。

时间局部性:

系统即将要用的信息可能就是现在用的。这是因为程序中存在大量的循环结构和子程序调用,在一段时间内会频繁访问相同的数据和指令。例如,在循环体中,会多次使用循环控制变量和循环体内的数据。

2. 多级存储层次结构的组成及原理

多级存储层次结构一般由寄存器、高速缓存(Cache)、主存(内存)、外存(如磁盘、磁带等)组成。

寄存器:速度最快,但容量最小,价格最贵。它直接集成在 CPU 内部,用于暂时存储 CPU 正在处理的数据和指令,与 CPU 的运算速度相匹配,可快速为 CPU 提供数据。

高速缓存(Cache):速度次之,容量也较小,价格相对较高。它位于 CPU 和主存之间,利用局部性原理,将主存中近期可能会被 CPU 访问的数据和指令复制到 Cache 中。当 CPU 需要访问数据时,先在 Cache 中查找,如果命中,则可以快速获取数据;如果不命中,则从主存中读取数据,并将该数据所在的块调入 Cache 中。这样,通过 Cache 可以减少 CPU 对主存的访问次数,提高存储系统的访问速度。

主存(内存):速度适中,容量较大,价格相对较低。它是计算机运行时程序和数据的主要存储区域,CPU 可以直接访问主存中的数据和指令。

外存(如磁盘、磁带等):速度最慢,但容量最大,价格最便宜。它用于长期存储大量的数据和程序,当需要使用这些数据和程序时,会先将其从外存调入主存中。

3. 多级存储层次结构的优势

通过多级存储层次结构,利用局部性原理,用较少的容量(如 Cache 的容量相对主存和外存来说较小),实现了较快的访问速度和较为实惠的价格。Cache 利用局部性原理,将近期可能访问的数据和指令缓存起来,提高了 CPU 的访问速度;而大容量的外存则以较低的成本提供了长期的数据存储能力。这样,在整体上,存储系统既满足了 CPU 对速度的要求,又满足了用户对大容量存储的需求,同时控制了成本。

越靠近CPU,越贵,越快,越小

一:cache性能分析和改进

时间:

平均访存时间=命中时间+不命中率*不命中开销

CPU时间=(CPU执行周期+存储器停顿周期数)*时钟周期时间

问题:对于一个CPI较小,时钟频率较高的CPU而言,cache不命中影响有双重:

--执行的CPI越小,说明固定周期数的Cache不命中开销就大,影响的指令数量就多

--计算CPI时,不命中的开销是周期数,所以哪怕访存时间一样,频率越高,影响的周期数就越多

所以对于一个低CPI高频率的CPU,Cache不命中代价很大

下面我们根据公式:

从不命中率.不命中开销和命中时间3个方面来考虑优化

二:降低cache的不命中率

(8个方法)

复习3C:

强制不命中(冷启动不命中)

定义:当程序首次访问某个数据块时,由于该数据块还未被调入 Cache,就会发生强制不命中。这种不命中通常发生在程序开始执行、Cache 为空的 “冷启动” 阶段,所以也被称为冷启动不命中。

优化策略:增加块大小。当块大小增加时,每次从主存调入 Cache 的数据量增多,后续访问同一数据块内其他数据时命中的可能性增大。例如,程序顺序访问数组元素,较大的块能一次性将更多相邻元素调入 Cache,减少后续元素访问时的强制不命中。

容量不命中

定义:当程序访问的数据量超过了 Cache 的容量,导致 Cache 无法容纳所有需要的数据,部分数据块会被替换出去,当再次访问这些被替换的数据块时就会发生容量不命中。

优化策略:增加 Cache 容量。更大的 Cache 可以容纳更多的数据块,减少因数据量超过 Cache 容量而导致的替换操作,从而降低容量不命中的概率。比如一个大型矩阵运算程序,若 Cache 容量过小,矩阵元素会频繁被替换出 Cache,增加 Cache 容量就能让更多矩阵元素留在 Cache 中。

冲突不命中

定义:在采用直接映射或组相联映射的 Cache 中,不同的主存块可能会映射到 Cache 的同一位置。当这些主存块需要同时驻留在 Cache 中时,就会发生冲突,导致其中一些块被替换出去,再次访问时就产生冲突不命中。

优化策略:提高相联度。相联度表示一个主存块可以映射到 Cache 中的多少个位置。提高相联度后,主存块的映射位置更加灵活,减少了不同主存块竞争同一 Cache 位置的情况,从而降低冲突不命中的概率。例如,从直接映射(相联度为 1)改为 2 - 路组相联映射,每个主存块有两个 Cache 位置可供选择,冲突的可能性降低。

优化策略带来的负面影响

块大小过大

块数量过少:Cache 的总容量是固定的,块大小增大,块的数量就会减少。这可能导致 Cache 的空间利用率降低,因为一个大的块中可能只有部分数据是程序近期需要访问的,而其他数据是无用的。而且,当发生不命中时,需要从主存调入一个大的块,会增加主存的访问时间和数据传输量。

Cache 命中率下降:如果块大小过大,可能会破坏程序的局部性原理。例如,程序可能只访问一个数据块中的开头部分,但由于块太大,将大量不相关的数据也调入了 Cache,占用了 Cache 空间,使得其他更需要的块无法进入 Cache,反而导致命中率下降。

Cache 容量变大

Cache 访问变慢:随着 Cache 容量的增加,Cache 的物理尺寸增大,信号传输延迟增加。同时,Cache 的地址译码和数据查找电路也会变得更复杂,这都会导致 Cache 的访问时间变长。例如,在大容量 Cache 中查找一个数据块可能需要更多的时钟周期。

相联度提高

硬件复杂度增加:提高相联度意味着在 Cache 查找时需要同时比较更多的 Cache 行。例如,在全相联映射(最高相联度)中,需要将主存地址与 Cache 中所有的块进行比较,这需要更多的比较器和控制电路,增加了硬件设计的复杂度和成本。

访问时间增加:由于需要进行更多的比较操作,相联度提高会使 Cache 的访问时间变长。例如,在一个 4 - 路组相联 Cache 中查找数据的时间通常会比直接映射 Cache 长,因为需要同时比较 4 个 Cache 行。

其他的5个方法:

-1-:伪相联Cache


结合了直接映射和组相联的优点

在逻辑上把直接映像cache空间平分为上下两个区

对于任意一次的访问,按照直接映像cache的方式去处理

如果正常命中,直接返回;否则去找找另一个区域的对应位置,如果找到了,那就是伪命中,否则去下一级存储器

优点是:命中时间短(直接映像),不命中率低(组相联)

缺点是:多种命中时间,我们需要保证大多数的命中都是快速的命中+

平均访存时间=命中时间+不命中率*不命中开销

            =直接命中时间+伪命中率*伪命中开销+不命中率*不命中开销

-2-:硬件预取:

将指令和数据预取放入cache or 外部缓冲器中(通常由cache之外的硬件完成)

两个研究成果:

指令预取

数据预取

如果采用流缓冲器(即可取出数据也可取出指令)

-3-:编译器控制的预取:

在编译期间加入预取指令,在数据被用到之前发出预取请求

做题时要观察规律,并且做好计算

预取的分类

放的位置分:

寄存器预取:把数据放在寄存器

cache预取:把数据只放在cache

预取的处理方式分:

故障性预取:出现虚地址故障or权限问题

非故障性预取:遇到这个预取时,不会发生异常,自动转化为空操作

编译器控制预取的特点:

--1:预取数据的同时要求处理器继续执行(非阻塞cache),要求执行和读取数据重叠执行

--2:循环是预取优化的主要对象

--3:每次预取花费一个指令的开销,我们要保证开销小于收益

-4-:编译器优化:

软件的方式来优化

要求:重新组织程序但是不影响程序的正确性

     如果一个转移指令很可能转移成功,会:把转移目标处的基本块和紧跟着分支指令后的基本块对调,把分支语句的语义取反

     数据对存储位置的限制较少,方便调整顺序

4个技术:

数组合并:

c[i]=x[i]+y[i]

提高空间上的局部性,让x[i]和y[i]同时取出来

内外循环交换

交换后有更好的局部性

循环融合:

重复访问相同的数组合

分块

把数组的按照行or列访问,改为按照块访问,这样访问更集中

同时利用了时间和空间的局部性

-5-:牺牲cache:

在cache和他的下一级存储器的通路之间设置一个全相联的小cache(牺牲cache)用来存放被替换出去的块

三:减少cache的不命中开销

(5个方法)

方法一:多级cache*(2级为例)

一级cache小而快,二级cache大,可以采用较高相联度or伪相联

区分局部不命中率和全局不命中率

这里主要考察做题,计算

方法二:让读不命中优先于写

由于写缓存器的存在,会导致我们读一些正在写回的数据要处理的问题过于复杂

解决办法:

--1:推迟读不命中的处理,知道写缓冲器清空

--2:检查写缓冲器的内容,没有相同的且存储器可用,就继续处理读不命中

方法三:写缓冲合并

处理思路:

如果写缓冲器为空,把数据和地址写入写缓冲器,这个时候cpu方面的写操作完成了

如果写缓冲器不为空,就看看有没有地址匹配的项,并且地址匹配的项的对应位置为空,那么就把这两次操作合并为一次写

如果写缓冲器满且没有可以合并的项,则等

方法四:请求字处理技术

请求字:从下一级存储器调入cache,只有一个字是立即需要的,那么这个字就是请求字

我们希望那请求字给CPU后:CPU今早重启动,请求字没有到达时,CPU等待,一旦请求字到达,就立即给CPU,让它尽早重启的,继续执行

调用块时,让存储器优先提供CPU需要的请求字,一旦到达就送给CPU,让其继续执行.同时从存储器调入该块其他需要的部分

(如果cache较小,下一个指令正好访问cache块的另外一部分,这个技术作用不大)

方法五:非阻塞Cache

采用记分牌orTomasulo算法,允许指令乱序执行,CPU无需再cache不命中时去等待

允许多次不命中,性能更高

并不重叠是不命中次数越多越好,研究表明一次不命中下的命中就可以获得所有的收益

四:减少命中时间

(4个方法)

方法一:使用小容量,结构简单的Cache

因为:性能高维护简便,成本较低。

方法二:虚拟Cache

物理cache需要地址转换和访问cache串行执行,比较缓慢

虚拟cache直接使用虚拟地址访问cache,省去了转换的过程,并且地址转换和访问cache并行,更快更合理

缺点:

需要避免不同进程的相同虚拟地址但是对应不同物理地址的问题(可以引入PID来改善)
也需要注意同义or别名的问题(同一个数据有两个不同虚拟地址下的副本):可以使用禁止or允许(并做好相关的配置)

解决方法(更进一步)

虚拟索引+物理标识:

方法三:cache访问的流水化:

Cache 访问流水化是把对第一级 Cache 的访问过程按照流水线的方式进行组织。流水线技术将一个复杂的操作分解成多个相对简单的子操作,每个子操作在不同的功能段上执行,且这些功能段可以并行工作。在 Cache 访问中,将整个访问过程(如地址译码、数据读取等 )划分为多个步骤,每个步骤在一个时钟周期内完成,这样在每个时钟周期都可以启动一个新的 Cache 访问操作,虽然单个 Cache 访问需要多个时钟周期才能完成,但整体上提高了 Cache 的吞吐率,使系统在单位时间内能够处理更多的 Cache 访问请求 。

方法四:踪迹cache

在追求每个时钟周期流出超过 4 条指令以开发指令级并行性时,难点在于要找到足够多彼此不相关的指令。踪迹 Cache 是应对上述挑战的一种解决方法。它存放 CPU 所执行的动态指令序列,这些序列包含了通过分支预测展开的指令 。分支预测是预测条件分支指令的执行方向,若预测为某个分支,就预先取出该分支上的指令放入踪迹 Cache 。不过分支预测不一定正确,所以在取到指令时需要确认预测是否准确。

优点:能够提高指令 Cache 的空间利用率。因为它根据程序实际执行路径存放指令,避免了普通 Cache 中可能存在的一些无用指令存储(如很少执行的分支上的指令 ),使得 Cache 空间更多用于存放真正会执行的指令。

缺点:

地址映像机制复杂。由于踪迹 Cache 存放的是动态指令序列,其地址映射不能像普通 Cache 那样简单基于静态程序地址,需要考虑分支预测、指令执行顺序等多种因素,增加了硬件实现的复杂度。

相同的指令序列有可能被当作条件分支的不同选择而重复存放。比如一个条件分支有两个可能路径,若分支预测不准确,可能会在踪迹 Cache 中多次存放相同指令序列,造成空间浪费。

相关文章:

计算机系统结构 第二章 :缓存优化

零-1:复习cache的基础知识: 一、映像方式 直接映射 原理:主存被分成若干区,每个区大小与 Cache 相同,区内再分块,主存每个区中块的大小和 Cache 中块大小相等,且每个区包含的块数也与 Cache 中块数相等。主存中任意…...

软件工程实践

例一 用例文档 UC1注册 执行者 潜在会员 前置条件 潜在会员访问系统 后置条件 系统已记录注册信息 涉众利益 潜在会员——希望注册尽量简单,希望自己的信息不会泄露 商店——希望获得尽可能多的未来客户信息,特别是联系方法 基本路径 1.潜在会员请求注册…...

将Airtable导入NocoDB

将Airtable导入NocoDB 0. 前提条件1. 详细步骤 NocoDB提供了一种简化流程,可在几分钟内将您的Airtable数据库无缝转移到各种数据库管理系统,包括MySQL、Postgres和SQLite。此功能特别适合希望将Airtable数据库迁移到更强大且可扩展的数据库管理系统中的用…...

【云备份】服务端数据管理模块设计与实现

目录 一、要管理的数据 二、如何管理数据 三.数据管理类的设计 3.1.数据信息结构体的设计 3.2.数据管理类的设计 四.数据管理类实现 4.1.数据信息结构体的数据填充 4.2.数据管理类的实现 五. 源代码测试 数据管理模块:需要管理的数据有哪些,而…...

Qt开发:按钮类的介绍和使用

文章目录 一、命令按钮类 (QPushButton)1.1 基本功能介绍1.2 常用构造函数1.3 常用方法1.4 信号与槽使用示例1.5 开关按钮(Checkable)1.6 创建出菜单按钮(Menu Button) 二、工具按钮类 (QToolBu…...

Clickhouse基于breakpad生成minidump文件,方便问题定位

背景 breakpad能够在程序崩溃的时候自动生成一个mini的core文件,能够帮助进行问题定位,但是clickhouse对于集成breappad的难度较大 查看github发现之前有大佬基于以前的分支有个MR,但是一直没有合并到社区,想来是有什么其他的原因…...

华为云Astro轻应用自定义连接器对接OBS云对象存储操作指南

操作难点图例(详细见下文详细操作步骤) 操作成功图例 说明:以下是通过自定义连接器创建新的OBS桶的图例 说明:以下是通过自定义连接器将数据内容嵌入创建新的OBS桶的图例 操作难点图例 说明:连接器编排需要注意的是动作选择、输入参数的设置等...

C# 运算符重载深度解析:从基础到高阶实践

运算符重载是 C# 中一项强大的特性,它允许开发者为用户自定义类型定义运算符的行为,使得代码更直观、更符合领域逻辑。本文将通过理论解析与实战示例,全面讲解运算符重载的实现规则、适用场景及注意事项。 一、运算符重载的核心概念 1. 什么…...

面试现场“震”情百态:HashMap扩容记

(以下为符合要求的文章内容) 【场景】 2024年秋招季某互联网大厂会议室 面试官:张工(P8级架构师) 求职者:马小帅(双非二本应届生) 第一轮提问(Java基础篇) …...

SCAU18124--N皇后问题

18124 N皇后问题 时间限制:5000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC Description 有N*N的国际象棋棋盘,要求在上面放N个皇后,要求任意两个皇后不会互杀,有多少种不同的放法? 输入格式 …...

MySQL 分库分表

对于使用 MySQL 作为数据库管理系统的应用来说,当数据量达到一定规模时,单库单表的架构会面临性能瓶颈,如查询缓慢、写入性能下降等问题。为了解决这些问题,可以使用分库分表技术。 二、为什么需要分库分表 2.1 单库单表的局限性…...

滑动窗口leetcode 904

代码&#xff1a; class Solution { public:int totalFruit(vector<int>& fruits) {int n fruits.size();unordered_map<int,int> window_type_count;int left 0;int ans 0;for(int right 0; right <n;right){while(window_type_count.size() 2 &&…...

用Maven定位和解决依赖冲突

用Maven定位和解决依赖冲突 一、依赖冲突的常见表现二、定位冲突依赖的4种方法2.1 使用Maven命令分析依赖树2.2 使用IDE可视化工具2.3 使用Maven Enforcer插件2.4 运行时分析 三、解决依赖冲突的5种方案3.1 排除特定传递依赖3.2 统一指定版本&#xff08;推荐&#xff09;3.3 使…...

八大排序之选择排序

本篇文章将带你详细了解八大基本排序中的选择排序 目录 &#xff08;一&#xff09;选择排序的时间复杂度和空间复杂度及稳定性分析 &#xff08;二&#xff09;代码实现 (三)输出结果 选择排序的基本原理是&#xff1a;每次从待排序的数组中找出最大值和最小值。具体流程是…...

SVM实战:从理论到鸢尾花数据集的分类可视化

SVM实战&#xff1a;从理论到鸢尾花数据集的分类可视化 在机器学习的广阔领域中&#xff0c;支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;作为一种经典且强大的分类算法&#xff0c;备受瞩目。它凭借独特的思想和卓越的性能&#xff0c;在模式识…...

深入解析 Stacking:集成学习的“超级英雄联盟

在机器学习的世界里&#xff0c;我们常常面临一个挑战&#xff1a;单一模型往往难以完美地解决复杂问题。就像漫威电影中的超级英雄们一样&#xff0c;每个模型都有自己的独特能力&#xff0c;但也有局限性。那么&#xff0c;如何让这些模型“联手”发挥更大的力量呢&#xff1…...

C# 编程核心:控制流与方法调用详解

在编程中&#xff0c;控制流和方法调用是构建程序逻辑的两大基石。它们决定了代码的执行顺序和模块化协作方式。本文将从基础概念出发&#xff0c;结合代码示例&#xff0c;深入解析这两部分内容。 控制流&#xff1a;程序执行的指挥棒 控制流决定了代码的执行路径&#xff0…...

PyTorch_张量基本运算

基本运算中&#xff0c;包括add, sub, mul, div, neg等函数&#xff0c;以及这些函数的带下划线的版本add_, sub_, mul_, div_, neg_, 其中带下划线的版本为修改原数据。 代码 import torch import numpy as np # 不修改原数据的计算 def test01():data torch.randint(0, 10…...

C++负载均衡远程调用学习之订阅功能与发布功能

目录 1.lars-DnsV0.1回顾 2.Lars-DnsV0.2-订阅功能的订阅模块分析 3.Lars-DnsV0.2-订阅模块的类的单例创建及方法属性初始化 4.Lars-DnsV0.2-发布功能的实现 5.Lars-DnsV0.2-发布功能的总结 6.Lars-DnsV0.2-订阅流程复习 7.Lars-DnsV0.2-订阅模块的集成 8.Lars-DnsV0.2订…...

接口测试的核心思维(基础篇)

1.为什么会进行接口测试&#xff1f; 早期发现问题&#xff0c;降低修复成本 当我们服务端已经完成&#xff0c;而前端还未进行开发的时候。我们可以通过接口测试避免前端的交互直接进行服务端的测试。 接口测试也能够更早介入项目的测试&#xff0c;降低修复成本。 提高测试…...

给文件内容加行号

题目&#xff1a; 给定一个文件&#xff0c;通过文件读写&#xff0c;给文件内容加行号。 行号形式如: 1:) xxXXXX 2:) xxxxXX 要求&#xff1a; 使用缓冲流操作。 思路分析&#xff1a; 程序定义了两个字符串变量 inputFile 和 outputFile&#xff0c;分别存储输入文件的路径…...

【计算机视觉】三维重建: MVSNet:基于深度学习的多视图立体视觉重建框架

MVSNet&#xff1a;基于深度学习的多视图立体视觉重建框架 技术架构与核心算法1. 算法流程2. 关键创新 环境配置与实战指南硬件要求安装步骤数据准备&#xff08;DTU数据集&#xff09; 实战流程1. 模型训练2. 深度图推断3. 点云生成 常见问题与解决方案1. CUDA内存不足2. 特征…...

终端与环境变量

一、我的电脑是Win10的&#xff0c;首先打开终端如下&#xff1a; 此时终端来到C:\Users\lenovo的目录下&#xff0c;可以访问该目录下的所有文件&#xff08;夹&#xff09;。另外&#xff0c;除了这个之外&#xff0c;终端还可以访问环境变量中的所有文件&#xff08;夹&…...

使用线性表实现通讯录管理

目录 &#x1f680;前言&#x1f99c;任务目标&#x1f31f;顺序表实现&#x1f40d;链表实现 &#x1f680;前言 大家好&#xff01;我是 EnigmaCoder。 本文介绍线性表的实验&#xff0c;使用顺序表和链表实现通讯录管理&#xff0c;包含初始化、插入、删除、查询、输出。 &a…...

机器学习常用评价指标

1. 指标说明 (1) AccuracyClassification&#xff08;准确率&#xff09; • 计算方式&#xff1a;accuracy_score(y_true, y_pred) • 作用&#xff1a; 衡量模型正确预测的样本比例&#xff08;包括所有类别&#xff09;。 公式&#xff1a; Accuracy TP TN TP TN FP…...

基于ArduinoIDE的任意型号单片机 + GPS北斗BDS卫星定位

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1.1 器件选择1.2 接线方案 二、驱动实现2.1 核心代码解析&#xff08;arduino/ESP32-S3&#xff09; 三、坐标解析代码四、典型问题排查总结 前言 北斗卫星导航…...

CGAL:创建点、线、三角形及其距离、关系

CGAL&#xff08;Computational Geometry Algorithms Library&#xff0c;计算几何算法库&#xff09;是一个强大的开源库&#xff0c;为众多几何计算问题提供了高效的解决方案&#xff0c;在计算几何领域应用广泛。以下将基于提供的代码示例&#xff0c;详细介绍如何利用 CGAL…...

STM32基础教程——软件I2C

目录 前言 I2C MPU6050 技术实现 原理图 连线图 代码实现 技术要点 I2C初始化 SCL输出和SDA输入输出控制 起始信号 停止信号 发送一个字节 读取一个字节 发送应答位 接收应答位 MPU6050初始化 指定地址写 指定地址读 读取数据寄存器 问题记录 前言 I2C …...

Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析

注&#xff1a;本文为 “Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析” 相关文章合辑。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 Xilinx FPGA 管脚 XDC 约束之&#xff1a;物理约束 FPGA技术实战 于 2020-02-04 17:14:53 发布 说明&#x…...

应用层自定义协议序列与反序列化

目录 一、网络版计算器 二、网络版本计算器实现 2.1源代码 2.2测试结果 一、网络版计算器 应用层定义的协议&#xff1a; 应用层进行网络通信能否使用如下的协议进行通信呢&#xff1f; 在操作系统内核中是以这种协议进行通信的&#xff0c;但是在应用层禁止以这种协议进行…...

大数据:数字时代的驱动力

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 随着互联网和技术的迅猛发展,数据已经成为现代社会最宝贵的资源之一。大数据(Big Data)作为一种全新的信息资源,正以前所未有的方式改变着各个行业的运作模式,推动着社会的进步与创新。无论是金…...

java学习之数据结构:二、链表

本节介绍链表 目录 1.什么是链表 1.1链表定义 1.2链表分类 2.链表实现 2.1创建链表 1&#xff09;手动创建 2&#xff09;创建链表类进行管理链表的相关操作 2.2添加元素 1&#xff09;头插法 2&#xff09;尾插法 3&#xff09;任意位置插入 2.3删除 2.4查找 1&…...

评估动态化烹饪工艺与营养实训室建设要点

在全民健康意识显著提升、健康饮食理念深度普及的时代背景下&#xff0c;烹饪工艺与营养实训室建设要点已不再局限于传统单一的技能训练模式。需以行业需求为导向&#xff0c;通过功能集成化设计推动革新 —— 将食品安全防控、营养科学分析、智能烹饪技术、餐饮运营管理等多元…...

Java学习手册:关系型数据库基础

一、关系型数据库概述 关系型数据库是一种基于关系模型的数据库&#xff0c;它将数据组织成一个或多个表&#xff08;或称为关系&#xff09;&#xff0c;每个表由行和列组成。每一列都有一个唯一的名字&#xff0c;称为属性&#xff0c;表中的每一行是一个元组&#xff0c;代…...

吾爱出品 [Windows] EndNote 21.5.18513 汉化补丁

[Windows] EndNote 链接&#xff1a;https://pan.xunlei.com/s/VOPLLs6DqKNz-EoBSWVRTSmGA1?pwd9isc# Thomson Scientific公司推出了2025&#xff0c;本次的endnote21大概率是最后一个版本啦&#xff0c;现已决定进行更新。 本次采用的环境为python3.12&#xff0c;win11&am…...

Sentinel学习

sentinel是阿里巴巴研发的一款微服务组件&#xff0c;主要为用户提供服务保护&#xff0c;包括限流熔断等措施 &#xff08;一&#xff09;主要功能 流量控制&#xff08;限流&#xff09;&#xff1a;比如限制1s内有多少请求能到达服务器&#xff0c;防止大量请求打崩服务器…...

【中间件】brpc_基础_execution_queue

execution_queue 源码 1 简介 execution_queue.h 是 Apache BRPC 中实现 高性能异步任务执行队列 的核心组件&#xff0c;主要用于在用户态线程&#xff08;bthread&#xff09;中实现任务的 异步提交、有序执行和高效调度。 该模块通过解耦任务提交与执行过程&#xff0c;提…...

Servlet(二)

软件架构 1. C/S 客户端/服务器端 2. B/S 浏览器/服务器端&#xff1a; 客户端零维护&#xff0c;开发快 资源分类 1. 静态资源 所有用户看到相同的部分&#xff0c;如&#xff1a;html,css,js 2. 动态资源 用户访问相同资源后得到的结果可能不一致&#xff0c;如&#xff1a;s…...

如何提升个人的思维能力?

提升个人的逻辑思维能力是一个系统性工程&#xff0c;需要长期训练和科学方法。以下是分阶段、可操作的详细建议&#xff0c;涵盖理论基础、日常训练和实战应用&#xff1a; 一、构建逻辑基础认知 1. 学习逻辑学核心理论 入门读物&#xff1a;《简单的逻辑学》麦克伦尼&am…...

[UVM]UVM中reg_map的作用及多个rem_map的使用案例

UVM中reg_map的作用及多个rem_map的使用案例 摘要:在 UVM (Universal Verification Methodology) 中,寄存器模型是用于验证 DUT (Design Under Test) 寄存器行为的重要工具。UVM 寄存器模型中的 uvm_reg_map(简称 reg_map)是寄存器模型的核心组成部分之一,用于定义…...

重新构想E-E-A-T:提升销售与搜索可见性的SEO策略

在2025年的数字营销环境中&#xff0c;谷歌的E-E-A-T&#xff08;经验、专业性、权威性、可信度&#xff09;已成为SEO和内容营销的核心支柱。传统的E-E-A-T优化方法通常聚焦于展示作者资质或获取反向链接&#xff0c;但这些策略可能不足以应对AI驱动的搜索和日益挑剔的用户需求…...

AI 采用金字塔(Sohn‘s AI Adoption Pyramid)

这张图是 Sohn 的 AI 采用金字塔&#xff08;Sohn’s AI Adoption Pyramid&#xff09; &#xff0c;用于描述不同程度的 AI 应用层次&#xff0c;各层次意义如下&#xff1a; 金字塔层级 Level 1&#xff1a;业务角色由人类主导&#xff0c;AI 起辅助作用&#xff0c;如 AI …...

影刀RPA中新增自己的自定义指令

入门到实战明细 1. 影刀RPA自定义指令概述 1.1 定义与作用 影刀RPA的自定义指令是一种强大的功能&#xff0c;旨在提高流程复用率&#xff0c;让用户能够个性化定制指令&#xff0c;实现流程在不同应用之间的相互调用。通过自定义指令&#xff0c;用户可以将常用的、具有独立…...

驱动总裁v2.19(含离线版)驱动工具软件下载及安装教程

1.软件名称&#xff1a;驱动总裁 2.软件版本&#xff1a;2.19 3.软件大小&#xff1a;602 MB 4.安装环境&#xff1a;win7/win10/win11 5.下载地址&#xff1a; https://www.kdocs.cn/l/cdZMwizD2ZL1?RL1MvMTM%3D 提示&#xff1a;先转存后下载&#xff0c;防止资源丢失&am…...

SQL经典实例

第1章 检索记录 1.1 检索所有行和列 知识点&#xff1a;使用SELECT *快速检索表中所有列&#xff1b;显式列出列名&#xff08;如SELECT col1, col2&#xff09;提高可读性和可控性&#xff0c;尤其在编程场景中更清晰。 1.2 筛选行 知识点&#xff1a;通过WHERE子句过滤符合条…...

2025深圳杯(东三省)数学建模竞赛D题完整分析论文(共36页)(含模型、可运行代码、数据结果)

2025深圳杯数学建模竞赛D题完整分析论文 目录 摘 要 一、问题重述 二、问题分析 三、模型假设 四、符号定义 五、问题一模型的建立与求解 5.1 问题一模型的建立 5.1.1 问题建模背景 5.1.2 特征工程设计 5.1.3 分类模型结构与数学表达 5.2 问题一模型的求…...

大数据技术:从趋势到变革的全景探索

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 在数字化时代的浪潮下,大数据已经不再是一个陌生的概念。从日常生活中的社交媒体,到企业决策支持系统,再到公共管理的大数据应用,它正在改变着我们的工作和生活方式。随着技术的进步,传统的数据…...

C++【内存管理】

C语言中的动态内存管理 int main() { int* p2(int*)calloc(4,sizeof(int)); int* p3(int*)realloc(p2,sizeof(int)*10); free(p3); }这里因为扩容数据小,所以是原地扩容,p2p3地址一样,不用free(p2) 如果扩容空间大就不是原地扩容,而是新找一块空间,然后拷贝 C内存管理方式 n…...

【Go类库分享】mcp-go Go搭建MCP服务

【Go类库分享】mcp-go Go搭建MCP服务 介绍 目前Go 生态圈有两个知名的开发 MCP 的库&#xff0c;一个是mark3labs/mcp-go,另一个是metoro-io/mcp-golang。 在介绍常用库之前&#xff0c;先来简单介绍一下mcp协议&#xff1a; MCP全称Model Context Protocol 模型上下文协议&a…...

人工智能发展史 — 物理学诺奖之 Hopfield 联想和记忆神经网络模型

目录 文章目录 目录1982 年&#xff0c;Hopfield 联想和记忆神经网络模型背景知识历史&#xff1a;霍普菲尔德简介神经学&#xff1a;大脑的联想记忆机制物理学&#xff1a;磁性材料的自旋玻璃理论和能量最小值函数 Hopfield 神经网络基本原理记忆存储&#xff08;训练&#xf…...