Config Store Bootstrap 详解
本文专述 Default / UniqueID 模式下 CPU 侧控制面 Bootstrap 的实现:TCP 建链、Config Store 键值协议、集合通信。不涉及 NPU / HYBM 对称堆。与 init_finalize.md 中 §3.2 Bootstrap 概要互补。
阅读建议:先读 init_finalize.md §3.2 了解模式选择与超时参数;本文从插件加载起展开 socket 与消息层细节。文中 PE 指参与 SHMEM 的单个进程(对应 my_pe / n_pes);源码标识符如 rankId、mype 保持与代码一致。
一、概述
1.1 拓扑
Default / UID 模式加载 aclshmem_bootstrap_config_store.so,形成 以 PE 0 为中心的星型拓扑:
各 PE(含 PE 0):均创建
TcpConfigStore客户端,经 同一 APIConnectToPeerServer(serverIp_, serverPort_, …)连向handle->ipport解析出的serverIp:serverPort(与 PE 0 listener 地址相同)。AccConnReq.rankId填my_pe;非 PE 0 的 connect 重试上限来自shm_init_timeout,PE 0 client 为固定 60 次(见 §五、§10.1)。仅 PE 0 额外启动 listener:
AccStoreServer在listenIp:listenPort上 accept 入站 TCP,维护内存 KV 表。PE 0 的 client 目标地址与其 listener 相同(通常为本机 IP + 端口),并非另一套 connect 方式。
Bootstrap 完成后,g_boot_handle.barrier / allgather 由 SmemNetGroupEngine 在 KV 表上实现,供 init 阶段 exchange_slice、aclshmem_malloc 同序等控制面同步使用。与后续 HYBM 设备堆建链无关。

图 1:PE 0 监听 KV 服务;各 PE 的 client 均 connect 至同一 serverIp:serverPort(Default ip_port 或 UID 广播)。
二、入口与调用链
2.1 总调用链
aclshmemx_init_attr()
└─ aclshmemi_bootstrap_init() [shmemi_bootstrap.cpp]
├─ 按 flags 选择插件、解析 ip_port / UID
├─ dlopen("aclshmem_bootstrap_config_store.so")
└─ aclshmemi_bootstrap_plugin_init() [shmemi_bootstrap_config_store.cpp]
├─ [UID 路径] 从 comm_args 构造 handle->ipport / sockFd / 超时
├─ config_store_set_tls_info / set_tls_key(L316-322)
├─ init_config_store() → TcpConfigStore::Startup
├─ init_group_engine() → SmemNetGroupEngine
└─ 注册 barrier / allgather / finalize
aclshmemx_get_uniqueid 走 pre-init 路径:aclshmemi_bootstrap_pre_init → config_store_get_unique_id(L45),在正式 init 前由 PE 0 生成 UID。
2.2 aclshmemi_bootstrap_init 分支
模式 |
插件 |
|
IP/端口来源 |
|---|---|---|---|
|
config_store |
UID 结构体指针 |
plugin 从 UID 提取 |
|
config_store |
UID 或 nullptr |
合法 |
|
bootstrap_mpi |
|
不走 Config Store |
Default 分支(shmemi_bootstrap.cpp L280–304):
is_valid_ip_port_url(attr->ip_port)为真 →use_attr_ipport=true,拷贝ip_port、sockFd、shm_init_timeout、control_operation_timeout。否则
is_uid_args_valid(comm_args)→ UID fallback(use_attr_ipport=false)。否则返回
ACLSHMEM_INVALID_PARAM。
is_valid_ip_port_url 要求 URL 为 tcp://host:port 或 tcp6://[host]:port,端口 > 1024,host 为合法 IP 或 hostname。

图 2:aclshmemi_bootstrap_init 模式分支 → plugin_init(含 TLS 配置)→ init_config_store / init_group_engine。MPI 模式不进入 config_store 路径。
三、IP 与端口解析
3.1 路径 A:use_attr_ipport == true(Default + 合法 ip_port)
字段 |
来源 |
用途 |
|---|---|---|
|
|
解析为监听/连接地址 |
|
|
PE 0 预绑定 listen fd(-1 表示由库 bind) |
|
|
非 PE 0 建链: |
|
|
barrier/allgather 超时(秒) |
多 instance:instance_id != 0 且 ip_port 非空、模板端口为 0 时,在 aclshmemi_instance_ctx_create(shmem_init.cpp)中调用 aclshmemi_instance_port_selection,按 SHMEM_INSTANCE_PORT_RANGE 替换端口;纯 UID(ip_port 为空且 comm_args 有效)跳过该步骤。
3.2 路径 B:UID / Default→UID(use_attr_ipport == false)
plugin_init(L280–314)从 comm_args 读取 aclshmemi_bootstrap_uid_state_t:
IPv4 →
tcp://{ip}:{port}IPv6 →
tcp6://[{ip}]:{port}handle->sockFd = uid_args->inner_sockFdhandle->timeOut = handle->timeControlOut = DEFAULT_TIMEOUT(120)。timeControlOut为控制面超时(秒);timeOut在 Config Store 中同样按 connect 重试次数 使用(见 §10.1)
写入 handle->ipport 后,所有 PE 的 serverIp_/serverPort_ 均指向 PE 0 公布的同一地址。
3.3 PE 0 生成 UID(config_store_get_unique_id)
环境变量 |
行为 |
|---|---|
|
解析固定 |
(未设置) |
|
aclshmemi_set_ip_info(store_net_utils.h)填充 aclshmemx_uniqueid_t 内 addr 与 inner_sockFd。PE 0 调用 aclshmemx_get_uniqueid 后须将 完整 UID 字节广播 给各 PE,各 PE 再 aclshmemx_set_attr_uniqueid_args。

图 6:aclshmemx_get_uniqueid pre-init 路径、IP/端口绑定与后续 init 衔接。库不负责 UID 广播。
3.4 URL 解析(建 Store 前)
init_config_store 调用 UrlExtraction::ExtractIpPortFromUrl(store_net_common.cpp),从 handle->ipport 得到:
option.ip:监听/连接 IP(hostname 会解析,不 fallback 到0.0.0.0)option.port:端口号(须 > 1024)
四、分层架构

图 7:自 aclshmemi_bootstrap_handle_t 至 Acclink TCP 的分层;KV 集合通信经 PrefixStore 前缀键实现,PE 0 额外嵌入 AccStoreServer listener。
组件 |
文件 |
职责 |
|---|---|---|
|
|
|
|
|
各 PE 的 Store 客户端;PE 0 额外嵌入 Server |
|
|
PE 0 KV 服务与消息分发 |
|
|
传输层(命名易混:client/server 均用此类) |
|
|
PE 0 accept 与连接级握手 |
|
|
基于 KV 的 barrier / allgather |
图 1(拓扑)与本图各组件对应关系见上表;PE 0 同时持有 listener 与 client 两条 TCP 路径,client 与其余 PE 使用相同 ConnectToPeerServer 入口。
五、建 Store:init_config_store
// shmemi_bootstrap_config_store.cpp:230-235
if (handle->mype == 0)
CreateStore(ip, port, isServer=true, rankId=0, connMaxRetry=-1, sockFd);
else
CreateStore(ip, port, isServer=false, rankId=mype, connMaxRetry=timeOut);
参数 |
PE 0( |
非 PE 0 |
|---|---|---|
|
|
|
|
有(与其余 PE 相同 API/目标地址) |
有 |
|
|
|
|
|
|
|
预绑定 listen fd 或 -1 |
未使用(传 -1) |
六、Socket 绑定与连接(核心)
6.1 PE 0:监听 socket 绑定什么
AccStoreServer::AccServerStart(store_tcp_config_server.cpp:33-41)设置:
listenIp = 从 URL 解析的 option.ip
listenPort = 从 URL 解析的 option.port
enableListener = true
sockFd = handle->sockFd(预绑定 fd,或 -1)
AccTcpListener::Start(acc_tcp_listener.cpp:110):
条件 |
行为 |
|---|---|
|
跳过 bind,在已有 fd 上 |
|
|
预绑定 fd 来源:
Default:
attr->option_attr.sockFd(用户已 bind 的监听 socket)UID:PE 0
get_uniqueid时inner_sockFd(aclshmemi_get_port_magic或aclshmemi_using_env_port产生)
监听地址为 URL 中的 具体 IP/hostname,不会自动绑定 INADDR_ANY。
6.2 各 PE 客户端 connect(统一路径)
TcpConfigStore::Startup(store_tcp_config.cpp:152-203)在 所有 PE 上执行相同 client 建链(PE 0 在 AccStoreServer::Startup 之后同样调用):
ConnectToPeerServer(serverIp_, serverPort_, connReq, retryMaxTimes, accClientLink_)
connReq.rankId = rankId_ // PE 0 为 0,其余为 mype
serverIp_/serverPort_:各 PE 相同,均来自handle->ipport解析,与 PE 0listenIp:listenPort一致。PE 0 client 连向 同一
serverIp:serverPort(通常即本机 listener 地址);非 PE 0 连向 UID 广播或 Default 中的 PE 0 地址——connect 实现与参数结构无差别,仅rankId与retryMaxTimes不同。
ConnectToPeerServer(acc_tcp_server_default.cpp:532):
CreateSocket(peerIp)→ IPv4/IPv6/hostname 解析。TCP_NODELAY、TCP_SYNCNT=1(快速 connect 探测)。循环
connect(),失败则 sleep(1),最多maxRetryTimes次。成功后
SO_RCVTIMEO = ACC_LINK_RECV_TIMEOUT(1800s),进入Handshake。
6.3 连接建立后的两条 socket 路径
路径 1 — 业务 KV(所有 PE)
TcpConfigStore::SendMessageBlocked
→ accClientLink_->NonBlockSend(seqNo, SmemMessage body)
→ PE 0 AccStoreServer::ReceiveMessageHandler
→ SET/GET/ADD/... Handler
→ 响应经 ReceiveResponseHandler 唤醒客户端
路径 2 — 新 PE 接入时的连接级握手(listener accept)
AccTcpListener accept 新 TCP fd
→ ProcessNewConnection:recv(AccConnReq)
→ (可选)TLS accept
→ HandleNewConnection:校验 magic/version → Initialize link → newLinkHandle_(AccStoreServer 为 LinkConnectedHandler,仅日志)
→ 将 link 加入 worker epoll
→ send(AccConnResp{result=0})
注意:KV 业务走 已建立的 accClientLink_;accept 线程上的 AccConnReq 用于 Acclink 内部对新入站连接的登记,与 Config Store 消息帧无关。

图 3:PE 0 监听;各 PE 经同一 connect API 建链;client/server 分列展示连接级握手;KV 业务独立于此。
七、Acclink TCP 握手
连接级握手在 AccConnReq / AccConnResp 上完成;Config Store 建链时在请求中携带 rankId(即 my_pe,store_tcp_config.cpp:201-202)。
7.1 客户端(主动 connect 侧,Handshake)
send(AccConnReq)整结构。(可选)TLS:
CreateSSLLink。BlockRecv(AccConnResp),要求result == ACC_OK。
7.2 服务端(accept 侧,ProcessNewConnection → HandleNewConnection)
AccTcpListener::ProcessNewConnection(acc_tcp_listener.cpp:300)recv(AccConnReq),长度须等于sizeof(AccConnReq),否则关闭 fd。(可选)TLS:
AccTcpSslHelper::NewSslLink。调用
HandleNewConnection(acc_tcp_server_default.cpp:361):magic / version 校验(L364-372):不匹配则拒绝;
Initializelink,调用newLinkHandle_(Config Store 上注册为AccStoreServer::LinkConnectedHandler,L170-174,仅打日志);EnableNoBlocking,worker->AddLink加入 epoll。
ProcessNewConnection发送AccConnResp{result=0}(L345-347)。
八、Config Store 消息协议
8.1 帧格式(SmemMessagePacker)
线上布局(store_message_packer.cpp:18-47):
[totalSize: u64]
[userDef: i64] ← GET 阻塞等待超时(ms);其他操作常为 0
[mt: i16] ← MessageType
[keyCount: u64]
重复 keyCount 次: [keyLen: u64][key bytes]
[valueCount: u64]
重复 valueCount 次: [valueLen: u64][value bytes]
Unpack 校验(L69-119):
buffer 长度须
Full()(≥ header 且 ≥ totalSize)。mt须满足SET ≤ mt ≤ INVALID_MSG(store_message_packer.cpp:83;合法业务类型为SET…CAS)。keyCount ≤ 10,每 key≤ 2048字节(server);client 侧 key 上限 1024。valueCount ≤ 10,每 value≤ 64MB。解析后
totalSize == 实际消费长度,否则失败。
8.2 消息类型与语义
类型 |
Client 请求 |
Server 校验与行为 |
|---|---|---|
SET |
1 key + 1 value |
写入/覆盖 KV;若 key 上有 GET 等待者则唤醒 |
GET |
1 key,无 value; |
有值立即返回;无值则阻塞至 SET 或超时(timer 线程) |
ADD |
1 key + 增量(十进制字符串) |
原子加;key 不存在则创建 |
REMOVE |
1 key |
删除;不存在返回 |
APPEND |
1 key + 字节块 |
追加;返回新总长度 |
CAS |
1 key + expect + new |
比较交换 |
非法类型、key/value 个数、长度 → INVALID_MESSAGE(-400)或 INVALID_KEY(-401)。
8.3 客户端发送与响应匹配
TcpConfigStore::SendMessageBlocked(L484-512):
分配单调递增
seqNo。注册
ClientWaitContext到msgClientContext_[seqNo]。accClientLink_->NonBlockSend(0, seqNo, dataBuf, nullptr)。阻塞等待
ReceiveResponseHandler按 相同 seqNo 唤醒,返回AccTcpRequestContext。调用方(如
Set/Get)对 response body 做Unpack,读取Header().result与 payload。
链路断开时 LinkBrokenHandler 唤醒所有 pending 请求为失败。

图 4:SmemMessagePacker 线上布局、Unpack 边界校验,以及客户端按 seqNo 匹配响应的流程。
九、SmemNetGroupEngine:barrier 与 allgather
9.1 键名前缀
init_group_engine:
PrefixStore(store, "SHM_(0)_") // DEFAULT_ID = 0
SmemNetGroupEngine::Create:
PrefixStore(store, "S_") // 静态组(bootstrap:option.dynamic=false)
// option.dynamic=true 时使用 "D_" 前缀(动态组 Join/Leave,非 Bootstrap 路径)
完整 key 示例:SHM_(0)_S_{groupVersion}_{sn}_BA。
9.2 GroupBarrier(store_net_group_engine.cpp:80)
对序号 idx = "{groupVersion}_{barrierGroupSn_}":
ADD idx_BA→ 返回值val(当前到达 PE 数)。若
val == rankSize(n_pes):最后到达的 PESET idx_BW = "ok"。全体
GET idx_BW,超时option_.timeoutMs(来自control_operation_timeout * 1000)。读到的值须等于
"ok"。val == 1且barrierGroupSn_ > REMOVE_INTERVAL(2)时,首个到达 PE 周期性REMOVE两轮前的{idx}_BA/{idx}_BWkey。
npes == 1 时 bootstrap barrier 直接返回(config_store_bootstrap_barrier L191-194)。
9.3 GroupAllGather(L207 起)
构造
{my_pe: u32}{payload}(线上字段名rankId),对idx_GA做 APPEND,返回累计字节数val。当
val == sendSize * rankSize,最后到达 PESET idx_GW = "ok"。全体
GET idx_GW等待完成,再GET idx_GA取全量 blob。按 embedded
rankId(PE 编号)排序,拷贝到recvBuf(每 PE 一段sendSize)。val == input.size()且allGatherGroupSn_ > REMOVE_INTERVAL(2)时,首个完成 APPEND 的 PE 清理两轮前的{idx}_GA/{idx}_GWkey(store_net_group_engine.cpp:231)。
Bootstrap 包装:config_store_bootstrap_allgather 要求 recv 缓冲区 ≥ len * npes。

图 5:键前缀 SHM_(0)_S_;SmemNetGroupEngine 在 KV 上实现的 barrier(ADD/SET/GET)与 allgather(APPEND/SET/GET/排序)协议。
十、超时、TLS 与多 instance
10.1 超时汇总
shm_init_timeout 命名与实现
对外字段名及 shmem_host_def.h 中 DEFAULT_TIMEOUT 注释均表述为 init 超时(秒)。在 Config Store 建链路径上,该值 不做秒→次数换算,而是原样传递:
option_attr.shm_init_timeout
→ g_boot_handle.timeOut [shmemi_bootstrap.cpp:289]
→ CreateStore(..., connMaxRetry) [shmemi_bootstrap_config_store.cpp:234]
→ TcpConfigStore::Startup(reconnectRetryTimes)
→ ConnectToPeerServer(..., maxRetryTimes) [acc_tcp_server_default.cpp:556]
ConnectToPeerServer 在 timesRetried < maxRetryTimes 循环内调用 connect(),失败则 sleep(1) 后重试。因此数值 N 表示最多 N 次 connect 尝试,最坏情况下约 N 秒 建链窗口(默认 120 与「120 秒超时」在数值上相近),但实现上是 重试次数上限,不是按 wall-clock 计时的超时器。
配置 |
典型值 |
作用 |
实现语义 |
|---|---|---|---|
|
默认 120(API 按秒命名) |
非 PE 0 连 PE 0 listener |
重试次数 → |
PE 0 client 建链 |
固定 60 次 |
与同 API,连本机 |
|
|
用户 attr(秒) |
barrier/allgather |
|
UID 路径 |
|
非 PE 0 建链 |
重试次数(与 |
|
1800s |
握手完成后 socket |
秒 |
GET 阻塞 |
请求内 |
Server 侧等待 key 出现的上限 |
毫秒 |
10.2 TLS
init 前:
aclshmemx_set_conf_store_tls/aclshmemx_set_config_store_tls_key写入g_boot_handle(shmem_init.cpp:681/696)。plugin_init在调用init_config_store之前,根据 handle 调用config_store_set_tls_info、config_store_bootstrap_set_tls_key(shmemi_bootstrap_config_store.cpp:316-322),写入StoreFactory。init_config_store入口随即SetTlsInfo(false, nullptr, 0)(L225),将StoreFactory::enableTls置为 false;CreateStore→InitTlsOption(store_factory.cpp:210-217)按此时enableTls与已缓存的 TLS 字段初始化tlsOption_。启用 TLS 时 listener 与 client 在
AccStoreServer::AccServerStart/TcpConfigStore::AccClientStart中按tlsOption.enableTls加载 OpenSSL 动态库并Start(AccTcpSslHelper)。
10.3 多 instance:g_store_ref
每次
plugin_init:g_store_ref++(L263)。config_store_bootstrap_finalize:g_store_ref--;仅当减至 0 时StoreFactory::DestroyStore()(TLS 清理线程)。各 instance 独立
ConfigStoreState与TcpConfigStore;全局 Destroy 不负责停止其他 instance 的连接。
十一、Finalize
11.1 调用位置与 control barrier
各 PE 在 aclshmemi_finalize_impl 中,于对称堆 / entity / default stream 释放完成之后、aclshmemi_bootstrap_finalize() 之前,调用 aclshmemi_control_barrier_all(),在 Config Store 上做一次 GroupBarrier(与 init 收尾、malloc 后 barrier 相同路径:g_boot_handle.barrier → config_store_bootstrap_barrier → KV ADD/GET)。
语义:全体 n_pes 均须 已进入 finalize 并到达该 barrier,之后才允许任一 PE 执行 Bootstrap teardown。PE 0 不会在尚有 PE 未到达 barrier 时关闭 listener。
aclshmemi_finalize_impl()
├─ team / signal / memory_manager / heap / entity / stream …
├─ aclshmemi_control_barrier_all() ← Finalize 控制面同步(Config Store GroupBarrier)
└─ aclshmemi_bootstrap_finalize()
└─ config_store_bootstrap_finalize()
├─ g_store_ref--
├─ [g_store_ref==0] StoreFactory::DestroyStore() // 仅 TLS 清理线程
├─ group_engine_ = nullptr
├─ store_ = nullptr → ~TcpConfigStore → Shutdown()
└─ delete ConfigStoreState
阶段 |
跨 PE 同步 |
说明 |
|---|---|---|
heap / stream 释放 |
无 |
各 PE 本地顺序执行 |
|
有 |
Config Store KV barrier;超时见 |
|
无 |
各 PE 本地拆 Bootstrap 连接 |
npes == 1 时 bootstrap barrier 直接跳过(与 init 阶段相同)。Finalize 流程图见 init_finalize.md §4.2 与 images/initialization/shmem_finalize_flow.png。
11.2 本 PE 资源释放(TcpConfigStore::Shutdown)
Barrier 通过之后,各 PE 进入 config_store_bootstrap_finalize → ~TcpConfigStore → Shutdown():
所有 PE(store_tcp_config.cpp:213-230):
accClientLink_ = nullptraccClient_->Stop()— 断开本 PE 到 PE 0 的 client TCP仅 PE 0 额外(
accServer_ != nullptr),在 client 停止之后 立即(store_tcp_config.cpp:226-228):AccStoreServer::Shutdown→accTcpServer_->Stop()(acc_tcp_server_default.cpp:109):先
StopAndCleanListener(L117)→ join accept 线程 →SafeCloseFd(listenFd_)再
StopAndCleanWorkers(L119)— teardown 仍连着的入站 TCP再
StopAndCleanDelayCleanup(L121)
join GET 超时
timerThread_(store_tcp_config_server.cpp:130-136)sockFd_ = -1
PE 0 在本地 Shutdown 内的顺序(与 AccTcpServerDefault::Stop 一致):
① 关 PE 0 自己的 client(accClient_->Stop)
② AccStoreServer::Shutdown → 关 listener → 关 server worker → delay cleanup
③ join timerThread_
因 barrier 已保证 全体 PE 均到达 finalize 拆 Bootstrap 前同步点,不会出现「其他 PE 尚未进入 finalize、PE 0 已关 listener」;若某 PE 从未进入 finalize,其余 PE 会在 §11.1 的 barrier 处阻塞直至超时,不会执行 aclshmemi_bootstrap_finalize。
11.3 能否保证「所有 PE 都释放」
维度 |
行为 |
|---|---|
已进入 finalize 的 PE |
barrier 通过后各自 |
未进入 finalize 的 PE |
已在 finalize 中的 PE 在 |
对称性要求 |
仍须 每个 PE 均调用 |
多 instance |
每 instance 独立 |
结论:Finalize 阶段在拆 Bootstrap 前有一次 control barrier;PE 0 监听端口在 barrier 通过且本 PE 执行 Shutdown 时释放。
11.4 Barrier 未覆盖的场景
Finalize barrier 只保证:已进入 finalize 的全体 PE 在拆 Bootstrap 前对齐(§11.1)。以下仍须应用保证:
(1)device 在途工作
aclshmemi_control_barrier_all 是 CPU 控制面 KV 同步,不等 device kernel / stream。而 heap、entity 等在 barrier 之前 已本地释放,若 device 仍有未完成 RMA,会在 finalize 过程中踩已释放资源。因此须在调用 aclshmem_finalize 前 完成 stream / kernel 同步(与 init_finalize.md §1.5 一致)。
(2)对称调用与 barrier 轮次
aclshmem_malloc / aclshmem_free 每次返回前都会经 aclshmemi_control_barrier_all 走一轮 Config Store GroupBarrier(§9.2,barrierGroupSn_ 递增);finalize 在 aclshmemi_bootstrap_finalize 前再调用一次同路径 barrier。各 PE 须 同序同大小参与 malloc/free,并 对称调用 aclshmem_finalize。
若运行期 malloc/free 未对称参与,各 PE 会停在 不同轮次 的 control barrier 上(例如部分 PE 等在 malloc 触发的 {sn}_BA,其余 PE 已推进到更后的序号)。此时若有 PE 先进入 finalize,会在 finalize 那一轮 barrier 上等待全员到齐;尚未进入 finalize 或仍卡在更早 malloc barrier 的 PE 不会加入同一轮,表现为:
已进入 finalize 的 PE:堵在
aclshmemi_bootstrap_finalize前的 control barrier;仍在 malloc/free 路径上的 PE:堵在该次分配/释放对应的 control barrier;
两边 barrier 轮次错配,互相等不到,finalize 侧直至 control_operation_timeout 失败,不会执行 aclshmemi_bootstrap_finalize。对称 finalize 本身也是同一机制:任一 PE 未进入 finalize,其余 PE 同样无法在同一轮 barrier 到齐。
场景 |
后果 |
|---|---|
malloc/free 未对称,部分 PE 先 finalize |
finalize 侧与 malloc 侧 barrier 轮次错配 → 分别堵在不同轮 barrier → finalize 超时,不执行 |
某 PE 未调用 |
已进入 finalize 的 PE 堵在 finalize 前 barrier → 超时 → 同上 |
全员 malloc/free 对齐且对称 finalize |
finalize barrier 到齐 → 各 PE 执行 |
device 已 sync |
避免 heap 释放后仍有在途 RMA(§11.4(1)) |
建议:device 同步完成 → 各 PE 对称调用 aclshmem_finalize → 库内 barrier 对齐后再拆 Config Store。
十二、PE 0 与非 PE 0 端到端时序
共性(所有 PE)
解析 相同
ipport(Default attr、UID 广播或 fallback)。TcpConfigStore::Startup→ConnectToPeerServer(serverIp_, serverPort_, rankId=mype, …)→ 握手 →accClientLink_。init_group_engine→ 参与 barrier/allgather。
仅 PE 0 额外步骤
CreateStore(isServer=true)→AccStoreServer::Startup:bind/listen于listenIp:listenPort(可在 client connect 之前 完成,使 listener 就绪)。client 连向与 listener 相同的
serverIp:serverPort;connMaxRetry固定 60,与shm_init_timeout无关。可选预绑定
sockFd供 listener 复用。
非 PE 0
CreateStore(isServer=false),无 listener。ConnectToPeerServer目标地址与 PE 0 client 相同;connMaxRetry = timeOut(来自shm_init_timeout或 UID 的DEFAULT_TIMEOUT)。
Finalize(与 §十一对应)
本地资源释放(team / heap / entity / stream)。
aclshmemi_control_barrier_all— 全体 PE 在 Config Store 上对齐。aclshmemi_bootstrap_finalize→ 各 PETcpConfigStore::Shutdown;PE 0 额外关 listener。
PE |
barrier 通过后释放 |
|---|---|
所有 PE |
client |
PE 0 额外 |
|
十三、源码索引
主题 |
路径 |
关键符号 |
|---|---|---|
Bootstrap 分支 |
|
|
插件入口 |
|
|
UID 生成 |
同上 |
|
IP/端口工具 |
|
|
Store 客户端 |
|
|
KV 服务端 |
|
|
消息编解码 |
|
|
集合通信 |
|
|
TCP 连接 |
|
|
监听 accept |
|
|
握手结构 |
|
|
十四、实现注意点
各 PE client 建链 API 相同;PE 0 额外持有 listener。PE 0 client 的
connMaxRetry固定 60,非 PE 0 用shm_init_timeout传入的上限。AccTcpServer是传输引擎名,每个 PE 都有一个 client 实例;listener 仅 PE 0 的AccStoreServer持有。连接级握手在 accept 路径校验
AccConnReq.magic/AccConnReq.version与AccTcpServerOptions是否一致;不匹配则拒绝(与 init_finalize.md 中connection_between_ranks.png“Check Magic” 步骤对应)。UID 生成依赖 env/ifa 绑端口逻辑;
magic在 UID 生成时写入,全体 PE 须字节级一致。hostname 监听/连接须能解析为具体地址,不会自动监听所有网卡。