尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

PyPTO 时序与重叠流水检视指南:early launch 下的跨流水共享状态、slot 复用与 OS 节流防护

发布时间:2026/9/20 1:36:50

资讯中心
01
ARTICLE

PyPTO 时序与重叠流水检视指南:early launch 下的跨流水共享状态、slot 复用与 OS 节流防护

PyPTO 时序与重叠流水检视指南:early launch 下的跨流水共享状态、slot 复用与 OS 节流防护
PyPTO 时序与重叠流水检视指南early launch 下的跨流水共享状态、slot 复用与 OS 节流防护【免费下载链接】pyptoPyPTO发音: pai p-t-oParallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto本文面向 PyPTOCANN 开源仓库framework/src/machine侧 C 改动检视系统讲解 skillpypto-machine-code-review的 §7 细则timing-race-rules.md在 early launch、整网压测等场景下ctrl / sche / aicore 三条流水重叠执行时如何判定共享字段可否按轮次改写、如何安全归还 slot 缓冲、以及硬失败等待为何必须覆盖 device OS 节流窗口。读完本文你将掌握一套可直接用于 PR 检视的时序竞态判定标准并能对照源码定位到具体实现佐证。一、背景三条流水重叠时的读者集合问题PyPTO 的动态执行由三类角色协作ctrlControl-Flow AICPU负责控制流、CF cache 记录/restore、资源预算memBudget与每轮启动参数DevStartArgs的编排scheSchedule AICPU负责任务调度入口处会拷贝devProg-devArgs将任务槽parallelDevTask / shake分发给 AICoreaicoreAIC / AIV 核真正执行算子任务异步读取 sche 派发的任务描述与 CF cache 数据。在 early launch 与整网压测下这三者经常叠着跑ctrl 自己这条流虽然是串行的但下一轮的 ctrl 会撞上上一轮还没跑完的 sche、aicore同时 device OS 会让单个 AICPU 连跑大约 950ms 后强制让出大约 50ms详见第四节。因此检视的核心心法只有一句不要看数据挂在哪个结构上要看还有谁在读。一个字段挂在DevProg上并不代表它属于 ctrl——只要 sche 或 aicore 也会读它、且每轮值会变它就属于跨流水共享状态不能按轮次原地改写。这条按读者集合reader set判定的思路贯穿全部三条规则。二、规则一先看谁在读再决定能不能改2.1 判定原则ctrl 和自己不重叠因此只有仅被 ctrl 使用的DevProg字段可以写。sche 或 aicore 也会读、且每轮值会变的字段不能在共享对象上原地改本轮值应放到DevStartArgs或按 slot 切开的 cache 里。原文档给出的字段归属表如下这是检视时的第一张对照表对象谁在读能不能按轮次改共享那份DevProg上 ctrl 自己用的字段ctrlFlowCacheAnchor、记录态 cache、memBudget补丁、ResetRerun等只有 ctrl可以写devArgs.nrValidAic/scheCpuNumctrl 和 sche 都读sche 入口会拷devProg-devArgs共享里只留满核容量本轮核数写到DevStartArgsring 头 /runtimeDataRingBufferInitedctrl 和 sche 都用走现成的申请/释放、等待 inited不要另改一套KernelArgs/ sharedBufferparallelDevTask、shakesche 和 aicore见规则二不能当本轮私有缓冲直接改slot 上 CF cache 的rawTensorAddrctrl 做 restore 时写aicore 读见规则二绕回前要等这个 slot 的 AICore 跑完判定PR 改了某个字段先列出 early launch 下还可能活着的读者。读者里有 sche 或 aicore且这个值每轮会变 →Blocker。2.2 源码佐证DevStartArgs 就是本轮状态的归宿dev_start_args.h 中DevStartArgs的定义明确承载了每轮拓扑信息struct DevStartArgs : DevStartArgsBase { ... // Per-round topology (ring slot local). Do not use shared DevProg.devArgs.nrValidAic across overlapping launches. uint32_t nrValidAic{0}; uint32_t scheCpuNum{0}; ... };源码注释直接写明了该设计的意图nrValidAic/scheCpuNum是ring slot 局部的每轮拓扑禁止在重叠 launch 之间使用共享的DevProg.devArgs.nrValidAic。这与规则一表格第二行的要求完全一致共享的devArgs里只保留满核容量每轮实际核数经DevStartArgs传递。在 device_execute_context.cpp 中可以看到每轮解析的用法// InitDyn already resolved per-round nrValidAic onto DevStartArgs; Submit only runs after RunInit sets args. const uint32_t nrValidAic args-nrValidAic;同时要注意反向风险device_task_context_drco.cpp 中仍存在devProg-devArgs.nrValidAic的直接读取。检视时若 PR 新增或移动此类读取点必须确认其执行时机不会跨轮次读取到被覆盖的值。2.3 ring 头与 inited 标志走现成协议runtimeDataRingBufferInited的写入与等待分散在两条流水ctrl 侧在 device_ctrl.h 完成 ring 初始化后置位devProg-runtimeDataRingBufferInited truesche 侧在 device_sche.h 用自旋等待消费while (unlikely(!devProg-runtimeDataRingBufferInited))。ring 头的申请/释放语义定义在 dev_start_args.h 的RuntimeDataRingBufferHeadAllocate/AllocatePrepare/AllocateSubmit/Deallocate、Full/Empty。规则一要求 ring 相关逻辑走现成的申请/释放、等待 inited不要另改一套——因为这些协议已经同时被 ctrl 与 sche 消费任何旁路改动都会破坏重叠执行下的先来后到。三、规则二槽位要等真正用完的人清干净再交给下一轮3.1 sche 退出 ≠ AICore 读完规则一管的是这个字段能不能改规则二管的是这块缓冲用完后怎么还。二者的核心差别在于sche 退出不等于 AICore 已经读完。Deallocate发生在 sche 都退出时这时 AICore 可能还在跑。因此还槽、停核的顺序必须是先让 STOP 被对面看见 → 再清槽 → 再 GOODBYE / 释放中间的 barrier 不能塞进可选分支例如if (NeedsFastPathRegClose)。early launch 下复用 slot 时restore 前要保证上一任 AICore 已经退出。判定出现下面任一情况 →Blocker。复用 ring slot / sharedBuffer / shake 时同步只等到 sche没有等到 AICore停核顺序不是「STOP 可见 → 清槽 → GOODBYE」或把 STOP 后的 barrier 放进可选 if。3.2 源码佐证BatchStopAllManagedCores 的标准停核序列aicore_manager.h 的BatchStopAllManagedCores是STOP 可见 → 清槽 → GOODBYE顺序的规范实现void BatchStopAllManagedCores() { aicoreHal_.SetReadyQueue(aicStart_, aicEnd_, AICORE_TASK_STOP 1); aicoreHal_.SetReadyQueue(aivStart_, aivEnd_, AICORE_TASK_STOP 1); /* write to MAINBASE reg must be done before close 0x18; * also make STOP visible before clearing parallelDevTask. */ __sync_synchronize(); if (aicoreHal_.NeedsFastPathRegClose()) { aicoreHal_.CloseFastPathReg(aicStart_, aicEnd_); aicoreHal_.CloseFastPathReg(aivStart_, aivEnd_); } // Clear shared parallelDevTask after STOP is visible, fence once, then // GOODBYE. Clearing too early races with aicores still reading ptrElements. aicoreHal_.ResetParallelDevTask(aicStart_, aicEnd_); aicoreHal_.ResetParallelDevTask(aivStart_, aivEnd_); __sync_synchronize(); aicoreHal_.ResetShakeBuf(aicStart_, aicEnd_); aicoreHal_.ResetShakeBuf(aivStart_, aivEnd_); }对照规则二逐条验证STOP 可见SetReadyQueue(..., AICORE_TASK_STOP 1)向 AIC/AIV 全部受管核下发 STOPbarrier 不能进可选分支NeedsFastPathRegClose()定义见 aicore_hal.h只是快速路径寄存器关闭的可选优化真正让 STOP 可见的__sync_synchronize()在 if 之外无条件执行且清 parallelDevTask 之前的 fence 不可省略再清槽STOP 可见后才ResetParallelDevTask源码注释明确警告Clearing too early races with aicores still reading ptrElements再 GOODBYE / 释放再一次 fence 后ResetShakeBuf即向waveBufferCpuToCore[CPU_TO_CORE_SHAK_BUF_GOODBYE_INDEX]写AICORE_SAY_GOODBYE的握手语义见 aicore_hal.h 与 aicore_hal.h。如果 PR 把清槽逻辑提前到 STOP 可见之前或把 barrier 挪进if (NeedsFastPathRegClose())就是规则二命中的典型 BlockerAICore 仍可能正在读parallelDevTask中的ptrElements槽位却被提前复位下一轮复用即触发数据竞争。3.3 slot 复用与 CF cache restore 的先后规则二同时约束了 CF cache slot 的复用slot 上 CF cache 的rawTensorAddr由 ctrl 在 restore 时写、aicore 读因此绕回reuse前要等这个 slot 的 AICore 跑完。在 device_execute_context.cpp 的 restore 路径中可以看到 ctrl 逐个恢复deviceTaskCacheList的dynTaskBase并对任务做RelocIncastOutcastTask、PredCountPingPongSwap、BitmapDataRestoreTask等操作这些写入都发生在 slot 交给下一轮之前必须以上一任 AICore 已退出为前提配合IsActivatedFullCache/bitmapRestoreDone等状态位判断。四、规则三等别的 AICPU、失败就报错的等待要盖过 OS 节流4.1 OS 节流的物理事实device OS 会让单个 AICPU 连跑约950ms后强制让出约50ms等待代码如果用的是硬件计数器让出期间时间照样走因此极短超时的 spin 等待可能在对方被节流的窗口内误判超时。这是 AICPU 侧自旋等待的底层物理约束所有超时设计都必须把它纳入预算。4.2 两条等待策略分界线超时就是功能失败、并且在等别的 AICPU 起来等待时间要 ≥GetOsThrottleSafeWaitTimeout()失败只是降级、或只是快速探测继续用短超时不要一律拉长拉长会拖慢正常路径的失败响应且可能掩盖真实故障。判定改了或加了 spin 等待先看失败后是直接报错还是降级。直接报错、对端又可能被节流 → 必须盖过节流窗口。4.3 源码佐证节流安全超时的实现与使用场景节流安全超时定义在 device_utils.h// 100ms规避 device OS 对单 AICPU 连跑 ~950ms 强制让出 ~50ms再叠加系统调度延迟后切回任务可能超过 55ms 的节流误超时 inline uint64_t GetOsThrottleSafeWaitTimeout(ArchInfo archInfo) { return (archInfo ArchInfo::DAV_3510) ? TIMEOUT_A5_100MS : TIMEOUT_A2A3_100MS; }注释给出了量级依据950ms 连跑强制让出 50ms叠加系统调度延迟后切回任务可能超过 55ms因此安全阈值取100ms按架构分 A5 / A2A3 两套常量见 device_utils.h 附近的TIMEOUT_A5_100MS/TIMEOUT_A2A3_100MS等超时族。同文件还定义了统一的超时档位索引与映射表TIMEOUT_INDEX_50US / 1SEC / 10SEC / 1MIN / 20MIN / HAND_SHAKE / DISPATCH与TIMEOUT_MAP_A2A3/TIMEOUT_MAP_A5见 device_utils.h方便检视时核对 PR 选用的超时档位是否落在功能失败等待的合理区间。硬失败必须盖节流、降级保持短超时的分界在 device_sche_wait_ctrl.h 的CalcWaitTimeout中有教科书式实现static inline uint64_t CalcWaitTimeout(ArchInfo archInfo, bool isOnlyOneSche false, bool isWaitCtrlLevel false) { if (isWaitCtrlLevel) { return IsDeviceMode() ? TIMEOUT_A2A3_1SEC : TIMEOUT_A2A3_10SEC; } if (!IsDeviceMode()) { return TIMEOUT_A2A3_1SEC; } uint64_t waitTimeout TIMEOUT_A2A3_100US; DEV_IF_INFO { waitTimeout TIMEOUT_A2A3_2MS; } DEV_IF_DEBUG { waitTimeout TIMEOUT_A2A3_3MS; } // 单 sche 超时直接报错需覆盖 OS 节流多 sche 超时仅降级丢线程保持短超时 if (isOnlyOneSche) { waitTimeout GetOsThrottleSafeWaitTimeout(archInfo); } return waitTimeout; }默认多 sche、可降级100usINFO/DEBUG 级别下放大到 2ms/3ms保持快速探测单 scheisOnlyOneSche超时直接报错无条件切换到GetOsThrottleSafeWaitTimeout(archInfo)100ms因为此时失败是硬失败必须盖过节流窗口。WaitCtrlRoundReady同文件 device_sche_wait_ctrl.h把arbitratedScheNum 1作为isOnlyOneSche传入即单 sche 下等待 ctrl 起来的 spin 也必须用节流安全超时。另一个使用点是 device_sche_alloc_thread.harbitTimeout osThrottleFallback ? GetOsThrottleSafeWaitTimeout(archInfo) : GetArbitTimeOutVal(archInfo);即仲裁等待在节流回退模式下同样切换到 100ms 安全档。4.4 检视时的超时分类速查失败性质对端超时策略源码示例硬失败直接报错别的 AICPU可能被节流≥GetOsThrottleSafeWaitTimeout()100msdevice_sche_wait_ctrl.h降级丢线程/跳过多 sche 之一保持短超时100us 起device_sche_wait_ctrl.h快速探测 / 轮询任意短超时 退出device_sche_alloc_thread.h 的TIMEOUT_A5_50US五、检视判定汇总与流程对接5.1 三条规则的判定卡片按读者集合判定可写性PR 改DevProg字段 → 列出 early launch 下仍活着的读者读者含 sche/aicore 且每轮变化 → Blocker仅 ctrl 使用 → 可写。先清后放复用 ring slot / sharedBuffer / shake 只等到 sche 没等到 AICore → Blocker停核顺序不是「STOP 可见 → 清槽 → GOODBYE」或 barrier 进了可选 if → Blocker。等待覆盖节流改了/加了 spin 等待先判失败性质硬失败 对端可能被节流却用远小于 100ms 的短超时 → Blocker降级路径无需拉长。5.2 与 skill 工作流的对接本文对应的 timing-race-rules.md 是 skillpypto-machine-code-review的 §7 细则详见 SKILL.md。命中 §7 的 PR涉及device_sche*/aicore_manager/device_ctrl/dev_start_args/device_launcher/ handshake / 超时 / ring / early-launch / sharedBuffer / 控核时必须加载本细则与 review-checklist.md 合并执行命中记录统一为{文件, 行号, 级别(Blocker/Major/Minor), 问题描述, 建议}。skill 的硬约束表对 §7 给出了两条高压线SKILL.md跨流水读者的本轮状态进DevStartArgs/ slot禁止按轮次原地改nrValidAic/scheCpuNum/ sharedBuffer 任务槽回收等 AICoreSTOP 可见 → 清槽 → barrier → GOODBYE禁止只等 sche 就复用 slot、fence 放进可选分支硬失败且等其他 AICPU 的等待 ≥ OS 节流窗口禁止硬失败路径继续用远小于节流窗口的短超时。违反 §7 /timing-race-rules.md即使功能正确也视为常稳回归。5.3 检视实操建议拿到 PR diff 后先用git diff $BASE..$PR_HEAD -- framework/src/machine/*聚焦 machine 侧排除 docs/tests 噪声对每个改动字段执行读者枚举在 early launch 重叠窗口内sche / aicore 是否仍可能读到旧值对新增的 spin 等待追查失败分支是return error还是降级处理再对照超时档位表device_utils.h核对所用超时对停核/还槽逻辑对照 aicore_manager.h 的标准序列逐句比对顺序与 barrier 位置。六、小结时序与重叠流水检视的三条规则本质是把跨流水共享状态的读写纪律落到三个可操作的检查点字段归属看读者集合而非结构挂载点规则一、缓冲归还等真正的消费者而非调度者规则二、等待预算覆盖对方被 OS 节流的物理窗口规则三。在 early launch 与整网压测下这三类问题不依赖特定的功能正确性而依赖对重叠执行窗口的完整建模——因此即便单轮执行一切正常时序违规也应判定为常稳回归Blocker。检视者可结合本文给出的源码坐标dev_start_args.h、device_sche_wait_ctrl.h、device_utils.h、aicore_manager.h快速完成对照验证。【免费下载链接】pyptoPyPTO发音: pai p-t-oParallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。