【UCIe】UCIe Stall 介绍

news2024/10/6 12:30:16


🔥点击查看精选 UCIe 系列文章🔥
🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥


📢 声明

  • 🥭 作者主页:【MangoPapa的CSDN主页】。
  • ⚠️ 本文首发于CSDN,转载或引用请注明出处【https://mangopapa.blog.csdn.net/article/details/128673906】。
  • ⚠️ 本文目的为 个人学习记录知识分享。因个人能力受限,存在协议解读不正确的可能。若您参考本文进行产品设计或进行其他事项并造成了不良后果,本人不承担相关法律责任。
  • ⚠️ 若本文所采用图片或相关引用侵犯了您的合法权益,请联系我进行删除。
  • 😄 欢迎大家指出文章错误,欢迎同行与我交流 ~
  • 📧 邮箱:mangopapa@yeah.net

文章目录

  • 1. 介绍
  • 2. Stall Message 复位 Timer
    • 2.1 链路初始化中的 Stall
      • 2.1.1 MBTRAIN.LINKSPEED 中的 Stall
      • 2.1.2 Adapter 参数交换中的 Stall
    • 2.2 链路管理状态转移中的 Stall
    • 2.3 寄存器访问中的 Stall
  • 3. pl_trdy 直接叫停 Flit 发送
  • 4. pl_stallreq/lp_stallack 握手暂停 Flit 发送
    • 4.1 Stallreq/Ack 机制
      • 4.1.1 pl_stallreq/lp_stallack 握手的 4 个 Phase
      • 4.1.2 补充说明
    • 4.2 pl_stallreq/lp_stallack 握手的使用场景
    • 4.3 pl_stallreq/lp_stallack Vs. pl_trdy
    • 4.4 Flit Stall 会引发 CompletionTimeout 吗?
  • 5. 退出 Stall
  • 6. 参考


1. 介绍

  UCIe 中有个 Stall 的概念,根据作用及载体的不同又可以细分为三类:

  • Stall Message 复位 Timer。这类 Stall 的载体是 Sideband Message,其作用为复位相关 Timer,防止出现不必要的 Timeout。
  • pl_trdy 直接叫停 Flit 发送。这类 Stall 可以由下层直接发起,上层立即响应。
  • pl_stallreq/lp_stallack 握手暂停 Flit 发送。这类 Stall 是通过 FDI 或 RDI 接口上的 pl_stallreq/lp_stallack 信号握手实现的,非及时响应,通过握手来暂停上层到下层的 Flit 传输,称为 Stallreq/Ack 机制。

  以上几种 Stall 中,pl_stallreq/lp_stallack 握手与 pl_trdy 有部分伴生关系,且均与 Stall Message 没有太大的关系。



2. Stall Message 复位 Timer

  实际上并不存在一种专有的用以 Stall 的 Message。这里说的 Stall 是 MsgInfo 的一种,能够携带 Stall MsgInfo 的 Message 有几十种。

  在 UCIe 中,对于需要 Response 的 Sideband 请求,要求请求发出后开始计时的 Timer 计时到 8ms 内收到 Response,否则就触发 Timeout。实际情况中,存在部分非异常的场景需要 8ms 以上的时间来回复 Response,比如链路传输时延较大,比如 Consumer 较忙来不及处理当前请求,此时不希望 Producer 报出 Timeout。

  为了解决以上问题,UCIe 定义了携带有 Stall 信息的 Sideband Message 来复位相关 Timer,以避免不必要的 Timeout。这类 Stall 主要用于链路初始化及协商、链路管理状态转移、Sideband 寄存器访问过程中。


2.1 链路初始化中的 Stall

  在 UCIe 链路初始化过程中用到 Stall 的地方有两处:MBTRAIN.LINKSPEED 及 Adapter 参数交换。


2.1.1 MBTRAIN.LINKSPEED 中的 Stall

  在带有 Retimer 的 UCIe 链路中,链路初始化处于 MBTRAIN.LINKSPEED 时,UCIe Retimer 之间发送的 {MBTRAIN.LINKSPEED done req}{MBTRAIN.LINKSPEED done resp} 需要携带 Stall 类型的 MsgInfo。不含有 Retimer 的不需要携带 Stall。


2.1.2 Adapter 参数交换中的 Stall

  在 UCIe Adapter 初始化过程中,协议要求在 Timer 计时到 8ms 内完成参数交换与协商,否则便会认定为参数交换失败并触发 Timeout。对于带有 Retimer 的 UCIe 链路(尤其是 Off Package 场景),其链路参数协商时间较久,极有可能触发 8ms Timeout。对于这种预期中的、不必要的 Timeout,可以在发生 Timeout 之前定时、周期性地发送带有 Stall 信息的 Message(协议要求是每 4ms 发送一次),来复位对端的相关 Timer,从而避免触发 Timeout。

  Adapter 参数交换中用到的 Message 有 {AdvCap.*}{FinCap.*},其中 * 可以为 Adapter 或 CXL。这些 Message 中的 MsgInfo 为 0000h (Reserved) 表示未携带 Stall 信息;在需要复位对端 Adapter 参数协商 Timer 时,将 MsgInfo 置为 ffffh (Stall),即发送 {AdvCap.*.Stall}{FinCap.*.Stall},表明当前 Message 携带了 Stall 请求,对端收到该 Message 后复位相关 Timer。这些 Stall 请求 Message 不需要对端反馈 Stall Ack。


2.2 链路管理状态转移中的 Stall

  请求对端进行链路状态转移时,需要发送 {LinkMgmt.*} 相关 Message,其中部分 Message 可以通过 MsgInfo=Stall (Response) 来重置 Timer。目前支持 Stall 的链路管理类 Message 如下:

  • {LinkMgmt.Adapter0.Req.Active}, For Retimer
  • {LinkMgmt.Adapter1.Req.Active}, For Retimer
  • {LinkMgmt.Adapter0.Rsp.Active}
  • {LinkMgmt.Adapter0.Rsp.PMNAK}
  • {LinkMgmt.Adapter0.Rsp.L1}
  • {LinkMgmt.Adapter0.Rsp.L2}
  • {LinkMgmt.Adapter0.Rsp.LinkReset}
  • {LinkMgmt.Adapter0.Rsp.Disable}
  • {LinkMgmt.Adapter1.Rsp.Active}
  • {LinkMgmt.Adapter1.Rsp.PMNAK}
  • {LinkMgmt.Adapter1.Rsp.L1}
  • {LinkMgmt.Adapter1.Rsp.L2}
  • {LinkMgmt.Adapter1.Rsp.LinkReset}
  • {LinkMgmt.Adapter1.Rsp.Disable}
  • {LinkMgmt.RDI.Rsp.Active}
  • {LinkMgmt.RDI.Rsp.PMNAK}
  • {LinkMgmt.RDI.Rsp.L1}
  • {LinkMgmt.RDI.Rsp.L2}
  • {LinkMgmt.RDI.Rsp.LinkReset}
  • {LinkMgmt.RDI.Rsp.LinkError}
  • {LinkMgmt.RDI.Rsp.Retrain}
  • {LinkMgmt.RDI.Rsp.Disable}

  以上 MsgInfo 支持 Stall 的 Message 中,Request 类型 Message 的只能由 Retimer 发出,Response 类型的 Message 无论是否 Retimer 都能发。

  Parity 协商发生于 Retrain 期间,Retrain 期间 Parity 协商相关 Message 也可以携带 Stall 类型的 MsgInfo,用到的 Message 为 {ParityFeature.Ack}{ParityFeature.Nak}


2.3 寄存器访问中的 Stall

  在 Sideband 寄存器访问场景中,由于寄存器访问请求 Message 处理优先级低也好,由于 Completer Busy 或 Not Ready 也好,无论什么原因导致 Completer 无法在 8ms 内回复 Status=SC/UR/CA 的 Completion,其必须先行回复 Status=Stall 的 Completion,每 4ms 发送一次,以复位相关 Timer。

  说到这里顺带提下 PCIe DMwr (《DMWr (Deferrable Memory Write) 详解》)的 Completion。PCIe 中,当 Completer 收到 DMWr 但无暇处理该 Memory Write 请求时,Completer 需要返回一笔完成状态为 RRS (Request Retry Status) 的 Completion 包来告知 Requester,Requester 可以(非必需)选择合适的时间重新发一次。同样都是无暇处理,PCIe 与 UCIe 采用的策略不同,PCIe 是 Requester 重传,“忙着呢,待会儿来找我”;UCIe 是 Requester 等一等,“好的,待会儿回复”。



3. pl_trdy 直接叫停 Flit 发送

  pl_trdy 为低时上层不可以往下层发送 Flit,pl_trdy=1->0 需要发生在 Flit 边界。pl_trdy=0 时,无法继续通过 lp_data_* 这组信号继续发送 Flit,但是 Flit Mode 下 FDI 接口上仍然可以通过 lp_dllp* 继续发送 DLLP(参照 lp_dllp_valid 信号描述)。

  这个较容易理解,不作过多解释。



4. pl_stallreq/lp_stallack 握手暂停 Flit 发送

  如果说上述 Stall 是 Sideband 上的事,那么接下来将的 Stall 就是 Mainband 上的事。Sideband 上的 Stall 用于重置 Timer,Mainband 上的 Stall 用于暂停 Flit 发送。Mainband Stall 是通过 FDI 或 RDI 接口上的 pl_stallreq/lp_stallack 信号握手实现的,通过握手来暂停上层到下层的 Flit 传输,称为 Stallreq/Ack 机制。


4.1 Stallreq/Ack 机制

  UCIe Stallreq/Ack 机制是一种 Mainband Flit Stall 请求应答机制,下层请求上层在 Flit 边界暂停发送 Flit。FDI 及 RDI 接口均需支持 Stallreq/Ack 机制。那么,上层可以请求下层进行 Stall 吗?显然不行,下层有数据发往上层时,上层必须接收,不能反压。


4.1.1 pl_stallreq/lp_stallack 握手的 4 个 Phase

  Stallreq/Ack 机制的具体实现是基于 FDI 或 RDI 接口上的 pl_stallreq/lp_stallack 这对握手信号,由下层发起请求,上层进行应答。一次完整的 pl_stallreq/lp_stallack 握手分为 4 个 Phase(图 1),包括 req/ack 的拉高及拉低握手过程(而非仅有拉高握手),如下:

  1. 下层拉高 pl_stallreq。下层将 pl_stallreq 拉高,发起 Stall 请求,请求上层 Flush 掉既有的 Flit,不要再生成新的 Flit 了。此时下层仍能够正常接收上层发来的数据。pl_stallreq 上升沿只能发生在 lp_stallack 为低的时候。若 lp_stallack 为高,表示此前进行的 pl_stallreq/lp_stallack 握手还在进行中,没必要重新发起握手请求。

  2. 上层拉高 lp_stallack。上层发现下层将 pl_stallreq 拉高之后,适时在 Flit 边界暂 Flit 传输并拉高 lp_stallack,以对 pl_stallreq 进行响应。lp_stallack=1 期间,lp_data 停止传输新的数据,lp_valid=0 且 lp_irdy=0,防止下层误解。lp_stallack 上升沿只能发生于 pl_stallreq 拉高期间,若 pl_stallreq 为低,没必要对齐进行响应。

  3. 下层拉低 pl_stallreq。下层收到上层发来的 lp_stallack=1 之后,得知上层已经确认暂停了 Flit 传输。然后,下层将 pl_stallreq 拉低,关闭之前的 Stall 请求。pl_stallreq 下降沿只能发生在 lp_stallack 为高或 reset 期间,若 pl_stallreq=1 时 lp_stallack 为低,表示上层还未对请求进行确认,或上层有故障再次取消了该确认信息。

  4. 上层拉低 lp_stallack。上层收到下层发来的 pl_stallreq=0 之后,得知下层已经关闭了之前的 Stall 请求,上层将 lp_stallack 拉低,关闭响应。lp_stallack 下降沿只能发生在 pl_stallreq 拉低或 reset 期间。

在这里插入图片描述

▲图1:pl_stallreq/lp_stallack 握手的 4 个 Phase

  在 UCIe Stallreq/Ack 机制的 pl_stallreq/lp_stallack 握手的 4 个 Phase 中,各个 Phase 之间的时间间隔并没有硬性要求。上层收到 pl_stallreq=1 后,并不要求立刻停止 Flit 传输,其不但能够继续发送当前 Flit 的剩余 Chunk,而且可以继续发送更多的 Flit,只需要找一个 Flit 边界暂停发送并响应以 lp_stallack=1 即可。同理,下层收到 lp_stallack=0->1 后不要求立刻将 pl_stallreq 拉低,上层收到 pl_stallreq=1->0 后也不要求立刻拉低 lp_stallack。但是出于性能考虑,在满足规则的前提下应尽快完成握手。当然也不能为了快就把 lp_stallack 到 pl_stallreq 的反馈环路做成纯组合逻辑,这种组合逻辑反馈环路容易有毛刺、震荡、实现违例等问题。为了避免组合逻辑反馈环路,在 pl_stallreq 与 lp_stallack 逻辑路径之间至少应包含一级 Flop。

  这里考虑一个问题,为什么要求在 Flit 边界进行 Stall 呢?直接停止不行吗?对于 PCIe 而言,Flit 是最小传输单位,不能发到一半后暂停发送。在 UCIe 中,受限于 lp_data 接口位宽,一笔 Flit 可能会分多个 Clock Cycle 进行发送。如果收到 Stall 后立刻停止 Flit 在 lp_data 上的传送,有可能会导致当前 Flit 被 Stall 割裂,这是不符合 PCIe 协议的。在收到 Stall 请求后,至少应该把当前在传的 Flit 传输完毕,确保是在 Flit 边界 Stall 住。


4.1.2 补充说明

  上文多次提到,上层可以自主选择一个 Flit 边界来暂停传输 Flit,这种说法是有争议的。
根据协议对 pl_stallreq 信号的描述,RDI 接口的 pl_stallreq 是状态转移过程中物理层请求 Adapter 发送端在 Flit 边界对齐并停止发送新的 Flit,FDI 接口的 pl_stallreq 是状态转移过程中 Adapter 请求协议层 Flush 掉所有未发出的 Flit 并停止生成新的 Flit。

  区别在于,FDI 要求了 Flush 所有 Flit,而 RDI 并没有这个要求。这样一来就有疑问了:

  • Adapter Tx Buffer 内还有未发出的 Flit 时可以暂停 Flit 发送吗?
  • 协议层收到 pl_stallreq=0->1 请求后,在响应 lp_stallack=0->1 之前还能继续生成新的 Flit 吗?
  • 协议层收到 pl_stallreq=0->1 请求后,可以不 Flush 完毕就暂停传输 Flit 并响应 lp_stallack=0->1 吗?

  欢迎留言私信与笔者进行讨论。


4.2 pl_stallreq/lp_stallack 握手的使用场景

  RDI 接口上,不论是 Raw Mode 还是 Flit Mode,在 RDI 状态由 Active 转为 Retrain、PM(L1/L2)、LinkReset 或 Disabled 之前,必须先进行 Stallreq/Ack 握手,确保 Adapter 发送完当前 Flit。

  FDI 接口上,Raw Mode 与 Flit Mode 在 pl_stallreq/lp_stallack 握手使用场景上有所不同。对于 Raw Mode,在 FDI 状态由 Active 转为 Retrain、PM(L1/L2)、LinkReset 或 Disabled 之前必须先进行 Stallreq/Ack 握手(笔者理解 Raw Mode 的 64B 相当于一个 Flit,也应遵守 Flit 边界对齐的规则)。对于 Flit Mode,在 FDI 状态由 Active 转为 PM(L1/L2)之前,必须先进行 Stallreq/Ack 握手,确保协议层发送完当前 Flit;对于 Flit Mode 时 Active 到其他状态的跳转,不要求 Stallreq/Ack 握手,只需 Adapter 在状态转移之前在 Flit 边界拉低 pl_trdy 即可。

  注意Flit Mode 时 FDI 的 pl_trdy 不会 Stall 住 lp_dllp* 信号传输 DLLP,但通过 pl_stallreq/lp_stallack 握手在 FDI 上对 Flit 进行 Stall 后,不但不能发送 Flit,也不能发送 DLLP

  同样都是状态转移,为什么 RDI 与 FDI 对是否需要 pl_stallreq/lp_stallack 握手的要求不同?同样都是 FDI 接口上的状态转移,为什么 Raw Mode 跟 Flit Mode 时对是否需要 pl_stallreq/lp_stallack 握手的要求不同?协议中未明确指出。笔者思来想去,倒是想到几种说法,但总感觉有些牵强附会。笔者辗转反侧,觉得以下说辞尚能解释得通:

  在对 pl_stallreq/lp_stallack 的握手需求上,RDI 跟 FDI Raw Mode 需求相同,FDI Flit Mode 自成一类。这几类的 Flit 有一大区别 —— Flit 中是否携带有效的 DLLP 信息。对于 FDI Raw Mode 及 RDI 上的 Flit 数据,有效的 DLLP (有的话)已经蕴含在了 Flit 中;而对于 FDI Flit Mode,其 DLLP 信息是与 Flit 解耦的(Flit 走 lp_data,DLLP 走 lp_dllp)。即便已经发起了 Active 到其他状态的状态转移请求,但在 FDI 或 RDI 状态由 Active 转为其他状态之前,Flit 是仍然在发送的,什么时候切换成功下层并不确定。既然 Flit 在发送,那么我们就需要 Credit 信息来决定是否能发 Flit。Credit 在哪获取?——在 DLLP 里。对于 RDI 及 FDI Raw Mode,如果采用 pl_trdy 来 Stall Flit,Flit 中的 DLLP 也一并被 Stall 住了,对端无法获的最新的 Credit 信息,这便存在一定的风险;对于 FDI Flit Mode,即便采用 pl_trdy Stall 住了 Flit,其 DLLP 仍能通过 lp_dllp* 到达 Adapter,Adapter 仍能获取到最新的 Credit 信息并发送给对端。当然 FDI Flit Mode 也能采用 pl_stallreq/lp_stallack 握手,但其不如 pl_trdy 来得痛快。

  从上述描述能够看出,不论是 RDI 接口还是 FDI 接口,其从 Active 退出到 LinkError 状态之前不要求 Stallreq/Ack 握手,笔者理解是因为上层先于下层知晓 Link Error 发生,并直接通过 lp_linkerror 信号通知下层,而非通过 lp_state_req 来请求下层进行状态转换,以此换来更快的响应速度。lp_linkerror=1 更像是一种上层发给下层强制性的命令,要求下层由 Active 转换到 LinkError 状态,不需要协商也不需要握手。

  从上述描述还能看出,协议中给出的 pl_stallreq/lp_stallack 握手全部发生于状态转换期间。那么,不涉及状态转换的时候是否可以进行 pl_stallreq/lp_stallack 握手来请求 Stall 呢?协议中未禁止亦未允许。笔者理解,若有 Stall 需求,直接用 pl_trdy 反压上层即可。

  还有一点,pl_stallreq/lp_stallack 握手只能发生于 Active 到其他状态的转换过程中吗?从非 Active 到其他状态的转移过程中就不需要吗?是的,不需要,没那个必要。一来,lp_stallreq 的定义中规定了 pl_stallreq 请求是用于状态转移中的;二来在这些状态中,除了 Active,还有哪个状态是能够传输 Flit 的?没有!连 Flit 都不能发,还谈何 Stall。


4.3 pl_stallreq/lp_stallack Vs. pl_trdy

  pl_stallreq/lp_stallack 握手与 pl_trdy 均能够暂停上层到下层的 Flit 传输,这两种有何区别呢?

  采用 pl_trdy 的方式来暂停 Flit 发送,下层具有绝对的主动权。当下层出于任何原因无法继续接收上层发来的 Flit 时候,下层直接在 Flit 边界把 pl_trdy 拉低,上层一定不能继续发送新的 Flit,立竿见影,简单有效。pl_trdy 的作用域仅限于 Local Die 的上下层,管不住对端。pl_trdy 只挡 lp_data 不挡 lp_dllp。

  采用 pl_stallreq/lp_stallack 握手方式来暂停 Flit 发送,上层具有较大的主动权。虽然 Stall 请求是由下层发起,但对 Stall 请求进行确认 Ack 权限在上层。上层可以不及时响应 Stall Req 继续发 Flit,笔者理解上层甚至都可以不理睬下层发来的 Stall 请求。如果上层长时间不对 pl_stallreq=0->1 进行反馈,请求的发起方应会有相关 Timeout 机制来应对该极端情况。pl_stallreq/lp_stallack 是伴随着状态转移的,状态转移是 UCIe 链路两端两个 Die 的事,状态转移完之前两端都会进行 Flit Stall。pl_stallreq/lp_stallack 既挡 lp_data 又挡 lp_dllp。


4.4 Flit Stall 会引发 CompletionTimeout 吗?

  既然涉及到 Flit Stall,那就不得不考虑一个问题:如果一笔携带有 NPR (Non-Posted Request) 的 Flit 在收到 Completion 之前就发生了 Flit Stall 且迟迟无法退出 Stall,会触发 Completion Timeout 吗?

  笔者理解,这取决于软硬件设计,不应该出现 Completion,但不排除这种可能。软件或硬件有责任在 Flit Stall 之前关闭 Completion Timeout 机制。如果关闭了,那就不会出现 Completion Timeout,否则是有可能出现的。如果非不关闭 Completion Timeout,大致有两种方案:① Timer 暂停;② 在 Timeout 之前恢复 Flit 传输。



5. 退出 Stall

  Sideband 上的 Stall 仅用于复位 Retimer,不在讨论范围之类。

  对于 pl_trdy=0 直接触发的 Flit Stall,在 pl_trdy=1 后即可继续发送 Flit。

  对于 pl_stallreq/lp_stallack 直接触发的 Stall,则需要 FDI 及 RDI 状态转换为 Active 且 pl_trdy=1 后方能继续发送 Flit。



6. 参考

  1. UCIe Spec r1.0


— END —


🔥 精选往期 UCIe 协议系列文章,请查看【 Chiplet 专栏】🔥

⬆️ 返回顶部 ⬆️

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

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

相关文章

【SAP Hana】SAP Hana存储过程开发

SAP Hana存储过程开发Hana 存储过程1、创建&更新语法2、删除语法3、调用语法4、实例演示(1)存储过程入门(2)指定 DEFAULT SCHEMA(3)定义内部变量,执行多个查询(4)定义…

【Javascript】高阶函数,JSON,forEach,map,filter,reduce等高阶函数,函数绑定

❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: 文章目录高阶函数箭头函数apply函数JSONfilter函数map函数总结reduce函数find/findIndex函数every/some函…

【Android安全】frida-gum教程

frida-gum教程 frida-gum概述 frida-gum是基于inline-hook实现的 提供的功能:代码跟踪(Stalker)、内存访问监控(MemoryAccessMonitor)、符号查找、栈回溯实现、内存扫描、动态代码生成和重定位 inline Hook 原理 .…

MySQL中常见的数值函数

第一个 ceil(x):向上取整 取整,顾名思义就是取整数; 向上取整是只要小数位不是 0,都会向上进 1 位整数。 案例 1: select ceil(9.2); 解析: 9.2 向上取一位整数,就是 10。 查询结果&#xff…

全屋智能品牌很多坑!选华为还是卡特加特数字家庭?技术角度分析亮了

市面上的智能家居品牌有很多,但拥有成熟全屋智能系统、完善产品体系,以及线下线上闭环销售渠道的则没几个。细数下来只有手机厂商华为、小米,以及科创型企业欧瑞博、摩根、UIOT和卡特加特,而其中以华为和卡特加特为代表的&#xf…

自定义类型:结构体,枚举,联合(3)

TIPS 1. 2. 枚举 1. 枚举顾名思义就是一一列举可能的取值,比如一周的星期一到星球天是有限的七天,可以一一列举。有比如性别,月份。 2. 像这种容易并且可以被一一列举的数据我们就可以定义为枚举类型。 枚举类型 1. 枚举的关键字为e…

【2】成功安装部署K8s集群

目录 1、安装方式 2、环境初始化 【1】主机名解析 【2】时间同步 【3】禁用iptables和firewalld服务(三台都要设置) 【4】禁用selinux(三台都要设置) 【5】禁用swap分区 【6】修改linux的内核参数 3、安装docker 【1】安…

自定义类型:结构体,枚举,联合(详解版)

🐋自定义类型:结构体,枚举,联合🦖结构体🐔1.结构体的声明🐤1.1 结构的基础知识🐤1.2 结构的声明🐤1.3 特殊的声明🐤1.4 结构的自引用🐤1.5 结构体…

APSIM实战练习:Kingsthorpe土壤水分蒸发研究

在本练习中,您将对来自澳大利亚昆士兰州金斯索普的真实试验的数据进行建模。使用从试验中观察到的数据,您将创建一个气象文件,模拟三个蒸发曲线并将模拟输出与观察到的数据进行比较。 有关试用的更多背景信息,请参阅此 PowerPoin…

操作系统-进程与线程

进程的概念、组成、特征 概念 程序:是静态的,就是存放在磁盘里的可执行文件,如:QQ.exe。 线程:是动态的,是程序的一次执行过程,如:可同时启动多次QQ程序。 组成 进程由PCB、程序…

Java数组(复习)

Java数组 数组:数组是指一种容器,可以用来存储同种数据类型的多个值 数组容器在存储数据的时候,需要结合隐士转换考虑。例如:int类型的数组容器,可以存储byte,short,int类型的数组。double类型…

矩阵乘GPU性能优化之split k

矩阵乘计算GPU实现中通常为线程块计算一个较大的[m_tile, k] *[k, n_tile]的矩阵乘,最后分配到每个线程后同样为每个线程计算更小的一个[m_tile, k] *[k, n_tile]。 这样存在的一个问题主要是在于m和n较小而k很大时,如下图所示的矩阵乘案例,…

总结各种常见的池子

池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。 池化技术的优点主要有两个:提前准备和重复利用。 像池化技术一些典型的池子就比如线程池,内存池,对象池,数据库连接池等等,线程…

cmake入门之一:编译、INSTALL及shell语句

cmake入门之一:编译、INSTALL及shell语句1.创建相应文件1.1 工程目录下CMakeLists.txt1.2 src文件夹1.2.1 src文件夹下main.c1.2.2 src文件夹下CMakeLists.txt1.3 runhello.sh1.4 其他文件/文件夹2.编译3.查看结果参考文献在学习cmake-practice这本书中的demo时&…

《基于机器学习的雷达辐射源分选与识别技术研究》论文解读

Data:2023-1-12 Ref: 李雪琼, “基于机器学习的雷达辐射源分选与识别技术研究,” PhD Thesis, 国防科技大学, 2020. 文章目录背景重频(PRI)基于已知信号的雷达分选技术基于未知信号的雷达分选技术这篇文章我主要关注他的第三、四章。第三章主要描述了基于已知信号的雷达分选技术…

《MySQL系列-InnoDB引擎15》文件-日志文件-慢查询日志

日志文件 日志文件记录了影响MySQL数据库的各种类型活动。MySQL数据库中常见的日志文件有: 错误日志(error log)二进制日志(bilog)慢查询日志(slow query log)查询日志(log) 这些日志文件可以帮助DBA对MySQL数据库的运行状态进行诊断,从而更好的进行数…

RTE 领域的发展,为视频编解码标准带来哪些新变化?丨Dev for Dev 专栏

本文为「Dev for Dev 专栏」系列内容,作者为声网资深视频算法负责人 戴伟。 01 视频编解码标准的历史和现在 1990 年左右 H.261 标准的制定,开启了视频编解码标准化的历程。经过 30 多年的努力,视频的编码效率得到了极大幅度的提升。在下图…

编程练习:找“单身狗“(三种解题法(不含暴力法))

目录 一.问题描述 二. 方法一:排序法 题解代码: 三.方法二:位运算法 第一步: 第二步: 第三步: 题解代码: 方法三:顺序表记录法 第一步: 第二步: …

c语言tips-【C语言多线程编程】

0.摘要 操作系统具有管理进程,进程调度的能力,线程,决定哪个进程、线程使用 CPU。很多时候我们需要在同一时间干不同的任务,这就需要我们通过多进程或者多线程来进行,在我们学习和工作中我们大部分用到的都是多线程,本…

SAP FICO 成本估算解析

成本估算解析 物料成本构成组件分类,比如下图中的G(Overhead)、L(Subcontracting)、E(Internal Activity)等。 同时它也分不同的视图,每个视图中包含了不同的组件。 对同一个工厂的同…