pcie 调试总结

2024-08-28 06:58
文章标签 总结 调试 pcie

本文主要是介绍pcie 调试总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


1  PCIE基本概念

1.1   PCIE拓扑架构图

 

https://img-my.csdn.net/uploads/201411/23/1416729836_6685.JPG

1.2 PCIE Switch内部结构图

 

https://img-my.csdn.net/uploads/201411/23/1416729836_4419.JPG

1.3  PCIE协议结构图

https://img-my.csdn.net/uploads/201411/23/1416729835_9165.JPG

 

1.4 PCIE枚举原理

1.4.1 Type0&Type1配置头空间

https://img-my.csdn.net/uploads/201411/23/1416729211_2569.jpg

1.4.2 拓扑示例

连接Device0的端口设为Port0,连接Device1的端口设为Port1 (Port可以看作PCI Bridge)

https://img-my.csdn.net/uploads/201411/23/1416731644_4271.JPG

1.4.3  枚举过程

Port0、Port1的相关Bus Register变化过程如下图

https://img-my.csdn.net/uploads/201411/23/1416731644_2181.JPG

1.5 资源分配

1.5.1 非桥设备资源分配

以Device0的资源分配为例:需要64KB IO Memory  以及 256 Byte IOPort 

(IOPort Base = 0x10000000,  IOMem Base = 0x20000000)

https://img-my.csdn.net/uploads/201411/23/1416729834_2212.JPG

1.5.2 桥设备资源分配

Port0为支持Devic0  IO & Memory Routing相关的Register设定 

https://img-my.csdn.net/uploads/201411/23/1416730055_4856.JPG

2,        配置空间

2.1 PCI配置空间

由于PCI/PCIe设备分为Bridge和Agent两种,所以配置空间也有两种类型:

其中Agent的配置空间类型称为Type 00h:

IMG_256

简单介绍其中的几个寄存器的意义:

Vendor ID,Device ID:标记了一个设备的生产厂商和具体的设备,比如Intel的设备Vendor ID通常是0x8086,Device ID就需要厂家自定义了,总之能够识别到具体是哪个设备就可以了。

Status:设备状态字,具体每个BIT的意义见下图:

IMG_257

Command:设备状态字:

IMG_258

Base Address Registers:决定PCI/PCIe设备空间映射到系统空间具体位置的寄存器,映射方式有两种,分别是IO和Memory映射:

IMG_259

IMG_260

处理器系统资源分为IO资源和MMIO资源两种,因此PCI/PCIe空间地址对应也有两种。

下面是Bridge的配置空间,它的类型被称为Type 01h:

IMG_261

Type 01h中也有Vendor ID,Device ID,Status,Command等寄存器。

另外需要注意的是这里的BAR计算得到的系统空间是该桥下挂的所有设备的系统空间的总和。

另外Subordinate Bus Number、Secondary Bus Number和Primary Bus Number,这些寄存器共同确定了该桥上行和下行的所有Bus号。

 

Base和Limit寄存器在Type1 Header中的位置如下图所示:

IMG_256

Base和Limit寄存器分别确定了其所有分支下设备(The device that live beneath this bridge)的地址的起始和结束地址。根据请求类型的不同,分别对应不同的Limit&Base组合:

·        Prefetchable Memory Space(P-MMIO)

·        Non- Prefetchable Memory Space(NP-MMIO)

·        IO Space(IO)

一旦该桥分支下面的任意设备的BAR发生改变,该桥的Base&Limit寄存器也需要做出对应的改变。

下面以一个简单的例子,来分析一下:

IMG_257

如上图所示,连接到Switch的PortB上的PCIe Endpoint分别配置了NP-MMIO、P-MMIO和IO空间。下面来简单地分析一下PortB的Header中的Base & Limit 寄存器。

P-MMIO Base & Limit

IMG_258

NP-MMIO Base & Limit

IMG_259

需要注意的是,Endpoint的需要的NP-MMIO的大小明明只有4KB,PortB的Header却给其1MB的空间(最小1MB),也就是说剩余的空间都将会被浪费掉,并且其他的Endpoint都将无法使用这一空间。

IO Base & Limit

IMG_260

注:IO空间可分配的最小值为4KB,最大值则取决于操作系统和BIOS

2.2 PCIe配置空间

PCIe是在PCI基础上发展的协议,PCIe也有上述的PCI配置空间,并且在此基础之上进行了扩展,其扩展形式是通过一种称为Capability的寄存器块来完成的。

PCI配置空间的大小是256个字节,即0x00~0xFF,而PCIe的配置空间扩大到了0x00~0xFFF,下图是具体的布局。

IMG_262

在原来的配置空间中,有一个寄存器指定了第一个Capability的位置,而第一个Capability又指定下一个Capability,构成了一串Capability,具体如下图所示:

IMG_263

各个不同的Capability的作用不同,且不同的设备有不同的Capability,在这里不一一介绍了。

 

2  PCIE事务交互

2.1 配置空间读写

Read Conf Space:  Device0 offset 4 

https://img-my.csdn.net/uploads/201411/23/1416742714_2090.JPG

2.2 内存空间读写

MMIO Read:  addr = 0x20000004

https://img-my.csdn.net/uploads/201411/23/1416742714_9985.JPG

2.3 中断发起、取消

https://img-my.csdn.net/uploads/201411/23/1416742241_9211.JPG

 

3, PCIe链路LTSSM状态机

我们知道,在PCIe链路可以正常工作之前,需要对PCIe链路进行链路训练,在这个过程中,就会用LTSSM状态机。LTSSM全称是Link Training and Status State Machine。这个状态机在哪里呢?它就在PCIe总线的物理层之中。

http://p9.pstatp.com/large/53f90002784ba617c98f

LTSSM状态机涵盖了11个状态,包括Detect, Polling, Configuration, Recovery, L0, L0s, L1, L2, Hot Reset, Loopback, Disable。这11个状态之间转换的逻辑,如下图,

http://p1.pstatp.com/large/53f800026fe1f2b0bc90

这11个状态大致可以分为4大类:

(1) PCIe链路训练相关。正常的PCIe链路训练状态转换流程依次是,Detect->Polling->Configuration->L0. L0是PCIe链路可以正常工作的电源状态。

(2) PCIe链路重新训练相关。这个状态也称为Recovery。Recovery是一个非常重要的链路状态,进入这个状态的因素也很多,比如电源状态的变化,PCIe链路速率的变化等。

(3) 电源状态相关。PCIe总线的电源状态主要有两部分的内容。

一是基于软件控制的PCI-PM电源管理机制,是系统软件通过修改寄存器中的电源管理字段,使PCIe设备进入D状态:D0,D1,D2,D3.

二是基于硬件控制的ASPM(=Active State Power Management)电源管理机制,是基于硬件自主控制的链路电源管理机制,只有在PCIe设备处于D0状态是才可以启动ASPM机制,另外,与ASPM有关的链路状态有L0s,L1(包括L1.1和L1.2).

(4)其他相关。比如Hot Reset, Link Disable, Loopback等。

我们接下来对这11个状态分别作一个简单的介绍。

Detect

这是物理层的初始状态,仅在Gen1 2.5 GT/s速率下使用,或是从数据链路层转换而来,或是在reset之后,或者从其他状态(Disable, Polling, Configuration,Recovery等)转换。总之,Detect状态是PCIe链路训练的开端。此外,Detect,顾名思义,需要实现检测工作。因为在这个状态时,发送端TX需要检测接收端RX是否存在且可以正常工作,如果检测正常,才能进入其他状态。Detect状态主要包含了两个子状态:Detect.Quiet和Detect.Active.

(1)从其他状态或者Reset之后,物理层从Electrical Idle开始,此时,处于Detect.Quiet;

(2)当超过12ms或者所有Lane均退出Electrical Idle时,则从Dectect.Quiet转换进入Detect.Active。在这个状态就会开启检测RX工作。

http://p1.pstatp.com/large/53fa000412292ceb83ea

判断RX是否存在的逻辑比较简单,就是通过一个“Detect logic”电路比较RC时间常数的大小。

(1) 当RX不存在时,RC时间常数较小。

http://p3.pstatp.com/large/53fb0003b06b6f4c6d71

(2) 当RX存在时,RC时间常数较大。

http://p1.pstatp.com/large/53f900061caeb8e50d81

Polling

这个状态的目的是"对暗号",实现无障碍沟通。进入这个状态后,TX和RX之间通过发送TS1、TS2 OS序列来确定Bit Lock, Symbol Lock以及解决Lane极性反转的问题。

Bit Lock: 在Bit传输过程中,RX PLL锁定TX Clock频率,这个过程称为RX实现"Bit Lock"。

Symbol Lock: RX端串并转化器知道如何区别一个有效的10-bit Symbol,这个过程称为“Symbol Lock”. 这里用到的是COM控制符。

Polling状态主要包含了三个子状态:Polling.Active, Polling.Configuration, Polling.Compliance.

http://p1.pstatp.com/large/53fb0005b867281626b6

(1) Polling.Active:这是链路从Detect退出后进入的状态,在这个状态下,发送端需要在所有Lane至少发送1024个TS1序列,因为接收端需要通过接收到的TS1序列来实现Bit/Symbol Lock. 由于发送端和接收端不是同时退出Detect状态,所以,TS1序列交流可能不会同步。此时,链路出于Gen1(2.5GT/s), Symbol time=4ns(10b/2.5Gb/s), 发送1024个TS1序列(16 symbols)至少需要64us(1024*16*4ns).

(2) Polling.Configuration: 当发送端TX发送完至少1024个TS1并且接收端RX连续收到8个TS1或者TS2,此时TS1和TS2中的Link/Lane区域由PAD填充, 那么,链路进入Polling.Configuration状态。处于此状态,发送端停止发送TS1序列,改为发送TS2序列,此时Link/Lane区域仍然由PAD填充,这个过程也会完成极性反转的问题,为进入下一个状态作准备。

(3) Polling.Compliance: 这个状态主要是通过发送不同的Pattern来测试发送端以及设备连接是否符合Spec要求。

Configuration

这个状态工作内容很简单,就是通过发送TS1、TS2来确定Link/Lane number. 如下图,Configuration包含了6个子状态:Configuration.LinkWidth.Start,Configuration.LinkWidth.Accpet,Configuration.Lanenum.Wait,Configuration.Lanenum.Accpet,Configuration.Complete, Configuration.Idle.

http://p3.pstatp.com/large/53ff0002edd6d360d585

由于Configuration状态下,发送端和接收端已经确认可以正常通信,所以,我们结合实例来看一下Downstream和Upstream的状态转换过程。

(1) Link Number Negotiation

Downstream在TS1中设定Link number, 此时Lane number=PAD,并发送给Upstream. 

 

http://p1.pstatp.com/large/53fd0006abe795d1d98e

而Upstream回的第一个TS1中,Link num仍然是PAD。此时,Upstream也处于Configuration.LinkWidth.Start状态。

http://p3.pstatp.com/large/53fc0006aee84cae9eb6

之后Upstream回的TS1中Link number则是设定值,此时, Upstream率先进入Configuration.LinkWidth.Accept状态。

http://p1.pstatp.com/large/540000061ebb8c93ab8b

到这里,Link Number Negotiation就完成了。

(2) Lane Number Negotiation

当Downstream看到Upstream返回的TS1中Link number已经是设定值,那么就认为Link num已经协商成功,然后就开始准备设定Lane number,此时Downstream链路也接着进入Configuration.LinkWidth.Accept状态. 由于在录这个Trace时有过滤重复的TS序列,所以,我们看到一个TS1序列对应了三个状态:Configuration.LinkWidth.Accept,Configuration.LaneNum.Wait,Configuration.LaneNum.Accept. 这个三个状态发送的TS1序列一样,Link number和Lane number都已设定。
 

http://p3.pstatp.com/large/53fe0006c131a59f3625

当Upstream收到Downstream设定Lane number的TS序列之后,也很快进入了Configuration.LaneNum.Accept状态。

http://p3.pstatp.com/large/567d0000891771b42eb4

与Lane number相关的三个状态之间相互转换逻辑如下:Downstream Vs Upstream.

http://p1.pstatp.com/large/567b00020a87add751d4

http://p3.pstatp.com/large/56780006c590bbe48b45

到这里,双方Lane number协议就完成了。

(3) Confirm Lane/Link Number

最后一步,过程就很简单了,双方通过发送TS2序列,对之前设定的Link/Lane number进行确认,这个过程,LTSSM处于Configuration.Complete. 确认没有问题之后,就准备进入下一个状态。

http://p1.pstatp.com/large/567b000229915c498ef7

L0

当进入这个状态时,PCIe链路就可以愉快的开始正常工作了。这个状态可以传输TLP,DLLP等报文。

Recovery

当PCIe链路需要重新训练时,进入Recovery状态。主要有以下几种情况:

(1) PCIe链路信号发现error,需要调整Bit Lock和Symbol Lock;

(2) 从L0s或者L1低功耗电源状态退出;

(3) Speed Change。因为第一次进入L0状态时,速率是2.5GT/s. 当需要进行速率调整5.0GT/s或者8.0GT/s时,需要进入Recovery状态进行Speed Change. 这个阶段,Bit Lock、Symbol Lock等都需要重新获取;

(4) 需要重新调整PCIe链路的Width;

(5) 软件触发retrain操作;

(6) 仅在Gen3和Gen4,需要重新进行Equalization。

Recovery子状态转换逻辑如下图:

http://p1.pstatp.com/large/567e0000d42a7ca0986a

我们结合一个上电过程中Gen1提速至Gen3的时序来解读一下Recovery状态的转换,如下图:

http://p1.pstatp.com/large/567b0003d27a2f52b833

a. Downstream率先进入Recovery.RcvrLock状态, 之后向Upstream持续发送TS1并且将speed_change bit设置为1;

b. Upstream端看到TS1进来之后,也跟着进入Recovery.RcvrLock状态,同时回传TS1序列,不过此时,speed_change bit仍为0. 当Upstream接收达到连续8个TS1且speed_change bit设置为1,这时,Upsteam回传的TS1、TS2中speed_change bit设置为1,并告诉Downstream建议工作速率,接着进入Recovery.RcvrCfg状态;

c. Downstream收到Upstream建议的速率反馈之后,也返回TS2序列,并发送EIOS序列,准备进入Electrical Idle. 此时,LTSSM处于Recovery.RcvrCfg状态;

d. 之后,Downstream和Upstream相继进入Electrical Idle, LTSSM处于Recovery.Speed状态;

e. 经过一段时间timeout(Spec要求至少800ns, 小编这个Trace中是~8us),Upstream发送EIEOS, 退出Electrical Idle, 尝试跑最高速率8GT/s;

f. 接着Downstream也退出Electrical Idle, 尝试跑试跑最高速率8GT/s;

g. 最后,双方开始进行EQ。EQ之后,PCIe链路就可以回到正常工作状态。

L0s/L1/L2

这三个状态,主要是低功耗电源管理状态,在这里不再展开了,具体可以参考Spec.

Hot Reset

当某个PCIe设备发生错误时,我们有时候需要通过软件的方式对设备进行复位,这个方式就是Hot Reset。可以通过设置Bridge Control寄存器中的Secondary Bus Reset来触发Hot Reset.

http://p3.pstatp.com/large/567d000298d51a04c8fe

Hot Reset的指令是在TS1序列中体现,如下图,

http://p1.pstatp.com/large/567d00029e9751a97cd7

Hot Reset触发之后,LTSSM会进入Recovery和Hot Reset状态,之后会到Detect状态,PCIe链路开始重新训练。

http://p3.pstatp.com/large/56790008610da19f44a8

Disabled

用户可以通过设置修改Link Control寄存器,让PCIe链路出于Disabled状态。

http://p1.pstatp.com/large/567a00044b7aff41b88d

另外,如果我们把设备移除之后,同样也进入Disabled状态。

当退出Disabled状态后,LTSSM回到Dectect,PCIe链路重新训练。

http://p3.pstatp.com/large/567d0002aafc11bdf883

Loopback

这个状态仅用于debug测试,一般情况不会遇到,在这里不再展开,有兴趣的话可以参考PCIe Spec.

4, Pcie capabilityregister datails

enable relaxed ordering

enable_pcie_relaxed_ordering

Attr字段由3位组成,其中第2位表示该TLP是否支持PCIe总线的ID-based Ordering;第1位表示是否支持Relaxed Ordering;而第0位表示该TLP在经过RC到达存储器时,是否需要进行Cache共享一致性处理。

一个TLP可以同时支持ID-based Ordering和Relaxed Ordering两种位序。Relaxed Ordering最早在PCI-X总线规范中提出,用来提高PCI-X总线的数据传送效率;而ID-based Ordering由PCIe V2.1总线规范提出。TLP支持的序如表5‑3所示。

表5‑3 TLP支持的序

Attr[2]

Attr[1]

类型

0

0

缺省序,即强序模型

0

1

PCI-X Relaxed Ordering模型

1

0

ID-Based Ordering(IDO)模型

1

1

同时支持Relaxed Ordering和IDO模型

当使用标准的强序模型时,在数据的整个传送路径中,PCIe设备在处理相同类型的TLP时,如PCIe设备发送两个存储器写TLP时,后面的存储器写TLP必须等待前一个存储器写TLP完成后才能被处理,即便当前报文在传送过程中被阻塞,后一个报文也必须等待。

如果使用Relaxed Ordering模型,后一个存储器写TLP可以穿越前一个存储器写TLP,提前执行,从而提高了PCIe总线的利用率。有时一个PCIe设备发出的TLP,其目的地址并不相同,可能先进入发送队列的TLP,在某种情况下无法发送,但这并不影响后续TLP的发送,因为这两个TLP的目的地址并不相同,发送条件也并不相同。

值得注意的是,在使用PCI总线强序模型时,不同种类的TLP间也可以乱序通过同一条PCIe链路,比如存储器写TLP可以超越存储器读请求TLP提前进行。而PCIe总线支持Relaxed Ordering模型之后,在TLP的传递过程中出现乱序种类更多,但是这些乱序仍然是有条件限制的。在PCIe总线规范中为了避免死锁,还规定了不同报文的传送数据规则,即Ordering Rules。

PCIe V2.1总线规范引入了一种新的“序”模型,即IDO(ID-Based Ordering)模型,IDO模型与数据传送的数据流相关,是PCIe V2.1规范引入的序模型。

Attr字段的第0位是“No Snoop Attribute”位。当该位为0时表示当前TLP所传送的数据在通过FSB时,需要与Cache保持一致,这种一致性由FSB通过总线监听自动完成而不需要软件干预;如果为1,表示FSB并不会将TLP中的数据与Cache进行一致,在这种情况下,进行数据传送时,必须使用软件保证Cache的一致性。

在PCI总线中没有与这个“No Snoop Attribute”位对应的概念,因此一个PCI设备对存储器进行DMA操作时会进行Cache一致性操作[1]。这种“自动的”Cache一致性行为在某些特殊情况下并不能带来更高的效率。

当一个PCIe设备对存储器进行DMA读操作时,如果传送的数据非常大,比如512MB,Cache的一致性操作不但不会提高DMA写的效率,反而会降低。因为这个DMA读访问的数据在绝大多数情况下,并不会在Cache中命中,但是FSB依然需要使用Snoop Phase进行总线监听。而处理器在进行Cache一致性操作时仍然需要占用一定的时钟周期,即在Snoop Phase中占用的时钟周期,Snoop Phase是FSB总线事务的一个阶段,。

对于这类情况,一个较好的做法是,首先使用软件指令保证Cache与主存储器的一致性,并置“No Snoop Attribute”位为1[2],然后再进行DMA读操作。同理使用这种方法对一段较大的数据区域进行DMA写时,也可以提高效率。

除此之外,当PCIe设备访问的存储器,不是“可Cache空间”时,也可以通过设置“No Snoop Attribute”位,避免FSB的Cache共享一致性操作,从而提高FSB的效率。“No Snoop Attribute”位是PCIe总线针对PCI总线的不足,所作出的重要改动。

 

5, PCIE 调试过程记录

1,  PCIE 物理层link 不稳定
LTSSM(Link Training and Status State Machine),各种status的code规范里都有定义。 这个LTSSM在PCIE Extend Config Space里面,PCIE 初始化完成后会进入L0状态。异常状态见PCIE link 异常log。 
物理层link 不稳定,怀疑以下原因: 
- 高速串行信号质量问题 
- Serdes电源问题 
- 时钟问题

a,  Serdes电源经过测量后,基本排除。 
b, pcie的RC和EP端使用了不同的pcie时钟IC,也就是说使用了非同源时钟。pcie specification中关于时钟的要求,并没有要求Host和EP端必须使用同源时钟。只是对同源、非同源时钟的精度做了要求。 
同源情况下要求100M. +-600ppm 
非同源时钟要求100M. +-300ppm 
解决方法: 
- 飞线成同一时钟源。 

 

2, 逻辑处理有问题,没有产生中断。

配置空间 status register 位 Interrupt Status

• Set when interrupt signaled by user.

• Clears when interrupt is cleared by the Interrupt

handler.

通过它来判断是否产生中断和处理中断。

 

6, XILINX PCIE IP 核配置

主要配置设备类型(RC, EP, 传统EP), lane width, and link speed。

 

定制厂商/产品, 产品类型码。

 

地址空间使能和配置。

 

中断配置: 传统中断,msi, msix。

 

7 信号质量调整

1,  发送预加重技术

传输信号的损耗核衰减对信号的完整性造成很大影响,表现为再传输线中信号沿的斜率变缓,导致码元宽度变宽, 在接收端接收到的信号幅度下降,抖动增加,从而导致信号眼图趋于闭合,造成接收端无法识别信号,误码率上升。

在传输信号发生跳变时,预加重电路可以对信号进行一定量的过驱动,

2,  接收均衡技术:

通过在接收端放大信号中的高频组分,低频组分基本保持不变,来补偿由于传输线的损耗而对信号造成的衰减。

建议在实际应用中尽量先使用接收均衡技术,在均衡技术无法补偿的情况下,再采用预加重技术。

手动调节均衡器有一个简单的控制参数用于设置高增益或低增益。

 

3,  PRBS 模式产生器

伪随机序列: PRBS 序列生成器电路,可以产生多种标准阶数的PRBS 序列,用于RX接收端对产生的PRBS 序列进行校验,校验的过程就是PRBS 产生的反过程,具体方法是RX接收端首先将收到的数据存入寄存器,然后将寄存的数据进行PRBS 编码,编码后的数据与最新接收到的数据进行比较,如果一致则表示PRBS 校验正确。

 

 

 

 

 

档铺网——在线文档免费处理

这篇关于pcie 调试总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114052

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;