CXLMemUring Update
1. 背景:CXL 与内存体系的演进
随着 CXL(Compute Express Link)对外设带宽和内存一致性需求的支持不断升级,越来越多的场景(如高性能计算、数据中心、AI 加速等)开始采用 CXL 的缓存一致性特性(CXL.cache)来让外部设备更灵活地访问主机内存。然而,这也带来了新的挑战:
设备的热插拔与故障风险
在传统的 PCIe/CXL.io 模式下,如果设备被热拔或因软硬件错误停机,通常只影响到 I/O 操作;但在 CXL.cache 模式下,外设有可能持有“Modified”状态的缓存行,一旦设备意外退出,则无法安全地将这些缓存行同步回主内存,可能导致数据丢失或更严重的系统级错误(如内核崩溃)。
安全性与侧信道风险
CXL.cache 在带来跨设备缓存一致性的同时,也暴露了更细粒度的访问通道。以往仅在 CPU 内部可能出现的缓存侧信道,如今可能演变为跨设备的安全隐患。
传统的防护方法(如粗粒度的地址访问控制)难以及时而精细地阻断潜在的恶意访问或侧信道攻击。
同步性能与延迟
随着更多设备加入一致性域,诸如共享队列、分布式归约(reduce)操作等场景的内存同步开销会显著上升。硬件需要更多手段来降低同步延迟。
Von Neumann Memory Wall 计算和存储之间的带宽与延迟矛盾依旧是系统瓶颈。即便有了 CXL.cache,对外设的访问在延迟和带宽方面仍难与 CPU 内部缓存层级相媲美。
基于这些问题,业界和学术界都在探索新的硬件/软件协作方案,以便在保证安全性的同时提升可靠性和性能。
2. 现有 SoTA(State-of-The-Art)方案及不足
2.1 现有典型方案
单向或异步加载/存储
通过在外设或内存侧增加多级缓冲或流水线机制,以期减少 CPU 对外设频繁通信时的阻塞。
在高性能计算或数据中心场景下,也有通过大页(Huge Page)、NUMA 优化等方法,减轻 CPU-设备间的通讯负担。
数据流加速器(Data Streaming Accelerator)
在 GPU、FPGA 或定制加速器中,往往引入类似 SPDK、DSA(Intel Data Streaming Accelerator)这样的技术,以批处理方式提升大吞吐数据操作的效率,减少内核干预。
大页或段级别的防护/隔离
在内存管理层面,通过页表标记等方式提供一定程度的访问隔离,把外设可访问的地址范围限制在特定分区/页中,避免无关的数据泄露。
2.2 现有方案的局限
Cache 污染与侧信道仍难彻底解决
即使采用大页或统一缓存一致性,外设在与 CPU 共享部分 LLC(Last-Level Cache)时,仍可能带来新的共享缓存侧信道。
粗粒度的防护手段难以阻止细粒度的攻击。
设备断开时的数据一致性问题
CXL.cache 模式下,如果关键数据一直处于外设的缓存行中(Modified 状态),当设备意外下线,将导致数据无法回写或者系统出现一致性错误。
目前缺乏一种硬件级的快速回退(rollback)或事务式保护机制。
同步操作的开销高
随着分布式、并行化的计算模式增多,共享数据结构(如环形队列、归约缓冲区等)的访问需要更多内存屏障或锁操作;跨设备的锁与屏障机制往往造成显著的延迟堆积。
编程与调试难度大
现有体系需要在设备驱动、内核、应用层多处改动;开发者若想在总线或内存级别做更灵活、更细粒度的管理,需要投入大量复杂的硬件/软件配合。
3. 新思路:在内存总线增加 eBPF-like 指令支持
为同时兼顾可靠性、安全性和性能,我们提出在主机与 CXL/root complex 之间增设一个“微型 eBPF-like 指令处理单元(tiny eBPF CPU)”的方案,核心思想如下:
总线级事务式内存操作(Transactional Memory on Bus)
允许外设将一组对关键控制面的内存写操作打包(类似 eBPF 程序),由总线侧的小型处理器执行并保证事务性。
如果事务执行中途外设意外断连或故障,整个事务可以回滚,避免出现“Modified”缓存行无人回写的情况。
这样一来,外设本身不再直接持有关键数据的独占/修改状态,也降低了热插拔带来的数据丢失风险。
可编程的细粒度安全检查
通过在总线侧维护一个可编程匹配表(matching table),结合 eBPF-like 指令,可以根据地址、访问模式、数据模式等进行快速检查和过滤;
实现类似 Linux seccomp 的“白名单”或“黑名单”机制,在更细的缓存行或地址范围上阻断可疑访问,减轻潜在侧信道攻击的风险。
降低同步延迟
由于部分跨设备的原子操作、锁或屏障可在总线侧以事务性执行,某些情况下比传统 DMA 往返更高效;
减少了软件层对外设状态的一致性管理负担,整体提升系统的并发性能。
灵活的可扩展性
eBPF-like 指令可以进一步应用于性能分析或诊断场景,比如在总线层监听和统计特定访问模式,以帮助开发者或系统管理员了解数据流分布,定位瓶颈或安全风险。
4. 实现策略
4.1 硬件结构与可能路径
CXL 专用实现
在 CXL Root Complex 侧增加一个微处理器核,用于执行 eBPF-like 指令包;
提供专门的 side-band 通道给外设发送这些指令包;
需在 CXL 规范中扩展或定义新协议字段,以实现对 CXL.cache 设备的安全事务化管理。
复用现有 NoC/总线协议
在诸如 TileLink、AMBA-AXI/ACE/CHI 等片上网络或总线协议中,加入 side-band 通道来传输 eBPF-like 指令;
好处是可以借助开源 IP 或既有总线生态,易于原型验证;
挑战在于,这些总线方案主要针对片上或极短距离的高带宽互连,如何说服审稿人或业界接受其“跨芯片”或外设场景,需要进一步探讨。
RISCV 扩展与软件评估
在 RISC-V 中扩展 LR/SC 指令序列,让 CPU 或总线能够将这些指令序列包装成 eBPF-like 程序并交给硬件执行;
有利于快速在软件层验证概念,可构建模拟器或 FPGA 测试平台来评估性能增益和安全增强效果。
4.2 关键设计点
事务内存 vs. eBPF
事务内存主要提供原子性和一致性保障;
eBPF-like 部分提供灵活的编程接口,用于地址匹配、安全策略执行、数据过滤等。
二者结合使得硬件具备高可编程性与安全回退的能力。
安全防护与可控回退
可在总线侧设置专门的访问策略:
对关键地址范围强制使用事务模式;
若外设故障,回退该事务并拒绝后续访问;
由此杜绝“Modified”缓存行无法回写的情况。
性能与兼容性
需要平衡新硬件引入的额外时延(如指令解析、表项匹配等)与带来的安全/可控好处;
对于普通访问,可走传统路径,不额外产生开销;
对需要安全/事务保障的访问,才使用 eBPF-like 处理器,减少对整体系统吞吐的影响。
5. 评估与展望
安全与Profiling演示
在小规模实验或原型系统中,通过 eBPF-like 指令完成地址过滤、访问统计,以及在外设异常时触发回退和阻断;
以此证明该方案能有效应对细粒度的安全风险。
事务内存的可行性
对比传统软件锁或 TSX(Intel Transactional Synchronization Extensions)等方式,验证在跨设备场景下,硬件级回退如何避免外设故障带来的数据丢失;
探讨如何防御 TSX 异步中止(Asynchronous Abort)等可能的攻击手段。
对现行 CXL Type 1/Type 2/Type 3 设备的兼容
如果只面向 CXL Type 2(带缓存一致性的设备),则需要在设计上确保对传统纯内存类设备(Type 3)或无缓存一致性的设备也能部分兼容;
在不同类型设备上分别测试性能和安全收益,形成全面的评估报告。
6. 总结
面对未来异构计算与内存层次日益复杂的趋势,“在内存总线增加 eBPF-like 指令支持”是一种兼顾安全性、可靠性及性能的前瞻性方案。它通过在总线侧对关键地址访问进行事务化处理并融合可编程逻辑,实现了:
避免设备热插拔和故障所引发的关键数据丢失;
在更精细的粒度上进行安全访问控制,减轻侧信道风险;
减少软件同步开销,提高分布式或并行场景下的整体效率。
尽管实现过程中需要对现行 CXL 或其他总线协议做出一定扩展,但从概念验证(PoC)到实际硬件落地,都具备可行的技术路线与潜在价值。后续仍需在事务内存模型、eBPF-like 指令的语义及安全性加固策略上持续探索与完善。
参考文献
- Fan Yao, et al. “CACo: A Comprehensive Approach to Cache Covert Channel Mitigation”, HPCA, 2018.
ChinaSys 2024 Fall
AI Chip
TrEnv
堆扩展不行
remote fork 容器本身。
SIGMETRICS
变长图
低比特量化
visually
like omnitable
Skyloft
NeoMem
failure durability
type 2 accelerator.
PTX JIT is better than NVBit.
undefined reference to `__sync_fetch_and_add_4'
You couldn't export builtin functions, but you can do hack with gcc
gcc -shared -fPIC -O2 atomic_ops.c -o libatomic_ops.so
#include <stdint.h>
#include <stdbool.h>
// Ensure all functions are exported from the shared library
#define EXPORT __attribute__((visibility("default")))
// 32-bit compare and swap
EXPORT
bool __sync_bool_compare_and_swap_4(volatile void* ptr, uint32_t oldval, uint32_t newval) {
bool result;
__asm__ __volatile__(
"lock; cmpxchgl %2, %1\n\t"
"sete %0"
: "=q" (result), "+m" (*(volatile uint32_t*)ptr)
: "r" (newval), "a" (oldval)
: "memory", "cc"
);
return result;
}
// 64-bit compare and swap
EXPORT
bool __sync_bool_compare_and_swap_8(volatile void* ptr, uint64_t oldval, uint64_t newval) {
bool result;
__asm__ __volatile__(
"lock; cmpxchgq %2, %1\n\t"
"sete %0"
: "=q" (result), "+m" (*(volatile uint64_t*)ptr)
: "r" (newval), "a" (oldval)
: "memory", "cc"
);
return result;
}
// 32-bit fetch and add
EXPORT
uint32_t __sync_fetch_and_add_4(volatile void* ptr, uint32_t value) {
__asm__ __volatile__(
"lock; xaddl %0, %1"
: "+r" (value), "+m" (*(volatile uint32_t*)ptr)
:
: "memory"
);
return value;
}
// 32-bit fetch and or
EXPORT
uint32_t __sync_fetch_and_or_4(volatile void* ptr, uint32_t value) {
uint32_t result, temp;
__asm__ __volatile__(
"1:\n\t"
"movl %1, %0\n\t"
"movl %0, %2\n\t"
"orl %3, %2\n\t"
"lock; cmpxchgl %2, %1\n\t"
"jne 1b"
: "=&a" (result), "+m" (*(volatile uint32_t*)ptr), "=&r" (temp)
: "r" (value)
: "memory", "cc"
);
return result;
}
// 32-bit val compare and swap
EXPORT
uint32_t __sync_val_compare_and_swap_4(volatile void* ptr, uint32_t oldval, uint32_t newval) {
uint32_t result;
__asm__ __volatile__(
"lock; cmpxchgl %2, %1"
: "=a" (result), "+m" (*(volatile uint32_t*)ptr)
: "r" (newval), "0" (oldval)
: "memory"
);
return result;
}
// 64-bit val compare and swap
EXPORT
uint64_t __sync_val_compare_and_swap_8(volatile void* ptr, uint64_t oldval, uint64_t newval) {
uint64_t result;
__asm__ __volatile__(
"lock; cmpxchgq %2, %1"
: "=a" (result), "+m" (*(volatile uint64_t*)ptr)
: "r" (newval), "0" (oldval)
: "memory"
);
return result;
}
// Additional commonly used atomic operations
// 32-bit atomic increment
EXPORT
uint32_t __sync_add_and_fetch_4(volatile void* ptr, uint32_t value) {
uint32_t result;
__asm__ __volatile__(
"lock; xaddl %0, %1"
: "=r" (result), "+m" (*(volatile uint32_t*)ptr)
: "0" (value)
: "memory"
);
return result + value;
}
// 32-bit atomic decrement
EXPORT
uint32_t __sync_sub_and_fetch_4(volatile void* ptr, uint32_t value) {
return __sync_add_and_fetch_4(ptr, -value);
}
// 32-bit atomic AND
EXPORT
uint32_t __sync_fetch_and_and_4(volatile void* ptr, uint32_t value) {
uint32_t result, temp;
__asm__ __volatile__(
"1:\n\t"
"movl %1, %0\n\t"
"movl %0, %2\n\t"
"andl %3, %2\n\t"
"lock; cmpxchgl %2, %1\n\t"
"jne 1b"
: "=&a" (result), "+m" (*(volatile uint32_t*)ptr), "=&r" (temp)
: "r" (value)
: "memory", "cc"
);
return result;
}
// 32-bit atomic XOR
EXPORT
uint32_t __sync_fetch_and_xor_4(volatile void* ptr, uint32_t value) {
uint32_t result, temp;
__asm__ __volatile__(
"1:\n\t"
"movl %1, %0\n\t"
"movl %0, %2\n\t"
"xorl %3, %2\n\t"
"lock; cmpxchgl %2, %1\n\t"
"jne 1b"
: "=&a" (result), "+m" (*(volatile uint32_t*)ptr), "=&r" (temp)
: "r" (value)
: "memory", "cc"
);
return result;
}
2024 年终总结
各位朋友,大家好。时间过得非常快,转眼又到年终岁末,想借这个机会做一个比较详尽、回顾式的总结,也为自己接下来的学习和工作做一个展望。接下来这段总结可能会稍微长一点,大概会花上十分钟的时间跟大家分享一下我今年的经历、感悟以及对未来的期待,希望大家能耐心听我唠一唠。
一、身体与心态的转折
今年的五到十二月,对我来说是一段并不算轻松的时光。由于生病的关系,我被迫中断了不少科研与学习的进度,也暂时离开了我非常热爱的技术领域。在那段日子里,身体上的不适与心灵上的焦虑常常相互影响,一方面我担心康复是否能够顺利,另一方面也忧虑自己是否会因此错过技术社区的更新迭代,以及可能涌现的新机会。
然而,这段“被迫停下脚步”的时间也给了我一个宝贵的缓冲期,让我能够更加冷静地思考:到底自己为什么会对 eBPF、WASM、CXL 等方向投入这么多的热情?到底想在未来的科研或工业实践中扮演怎样的角色?我慢慢意识到,保持对世界的好奇、享受做科研和技术探索的乐趣,其实才是我内心深处最坚定的东西。这也让我对自己今后的人生布局有了更清晰的感受和方向——求真、探索和创造比起一时的成就和荣誉似乎更重要。
二、回顾与反思:从好奇心出发
我一直觉得,一个人能够持续走得远,最大的动力往往是源自内心深处的好奇心。在这一年里,虽然有一段时间我无法亲身投入各种项目和话题的第一线,但我一直在关注产业和学术界一些新的动态,也不时阅读各种新闻、博客和技术更新,让我在“被迫停下来”的期间依旧保持对行业的敏感度。
- eBPF(Extended Berkeley Packet Filter)
之所以对 eBPF 感兴趣,是因为它为内核态与用户态之间的灵活沟通提供了前所未有的机会。在内核层面,对网络、跟踪、可观测性、安全策略等的精细控制,让我看到操作系统领域新的可能性。尽管它背后的概念已经出现多年,但近几年的蓬勃发展证明了它在云原生时代和超大规模分布式系统中仍有很大的增长空间。 - WASM(WebAssembly)
WebAssembly 近几年从前端扩展到后端,甚至已经进入云计算和边缘计算的范畴。它高度跨平台、可移植、高效的特性,让我看到未来在容器化和函数计算层面的更多机会。我一直好奇 WASM 是否会在云端或边缘带来类似当年 Docker、Kubernetes 带来的生态变革,毕竟能够在各种硬件、各种语言环境下运行的可移植性,对整个行业来说是非常有吸引力的。 - CXL(Compute Express Link)
这是一个让存储与计算之间实现更紧密交互的新兴技术标准,尤其适用于数据中心、云计算以及对计算与存储性能要求极高的场景。CXL 提供了一种共享和统一管理内存或加速器资源的方式,让我对未来服务器架构和高性能计算的演进充满好奇。我想,如果 eBPF 和 WASM 关注的是“软件层面的革新”,那么 CXL 则是硬件层面的重大突破。有时候,把眼光放到系统堆栈的更底层,也能带来全新的灵感和思考。
这些领域都各自处于技术发展的前沿,也都有各自的挑战。我很喜欢这种“万花筒”般的世界:变化既是挑战,也是机遇,旧的知识会逐渐被新思路取代;新人只要肯投入时间和精力,就能找到可以施展的空间。这种迭代的活力深深地吸引着我,也让我一直想要在学习或工作中关注更广、更深的领域。
三、拥抱变化:科研、工业和开源
在回顾这一年、反思自身状态的时候,我发现自己心中始终有一个纠结:究竟是继续在学术界深耕,比如考虑读博士、做研究;还是去工业界寻找更直接的项目落地场景?亦或是投身开源社区,在一个大家庭里共同打磨一款产品?
其实,这三种方向并不一定相互排斥。正如许多成功的前沿技术往往源自学术研究,再经过开源社区的孵化,最后才在工业界大规模应用。我看到 eBPF、WASM、CXL 也在走着类似的路径:先由少数极客在学术或社区环境中推波助澜,逐渐积累,形成一定规模,再被大企业收购或引入到正式的生产环境。我个人非常希望能在这个过程中尽一份力,从早期就参与其中,并在学术和工业应用上都能获得成长与磨砺。
1. 学术探索
我对学术研究的热爱,更多是对于“未知领域的好奇”。学术研究可以让我沉下心来思考:技术背后更底层、更本质的问题在哪里?这样的问题往往并非一朝一夕就能解决,需要的是长时间的积累和深度思考。同时,研究的过程也能让我对事物有更全面和系统的认识,哪怕只是在科研群体的圈子里互相切磋,也能激发创新火花。
2. 工业场景
工业界的实践能带给我更多“真刀真枪”的挑战。如何解决海量数据带来的网络瓶颈与安全风险?如何提升系统性能、减少资源浪费?这些问题没有现成的标准答案,需要我们从需求出发,结合实际的工作负载和使用场景去做权衡。eBPF、WASM 和 CXL 在这一领域都大有可为:前者能在内核层实现灵活的策略定义与性能分析,后者可为跨平台运行与硬件加速提供新的方案。
3. 开源社区
我相信开源社区代表了一种更加开放、自由的创新方式。只要感兴趣,任何人都可以在全球范围内基于同一个代码库、文档、工具集做出贡献和探索。像 Cilium(基于 eBPF 的网络与安全),这些开源项目已经有了可观的商业价值,也吸引了许多开发者。我非常向往这种“你一行代码、我一行代码,大家一起把未来拼出来”的氛围,既能让技术传播更广,也能帮助个人在更短的时间里融入国际化的技术浪潮。
四、展望未来:持续好奇、持续前行
经历了生病的休整和对未来的沉淀思考,我在下半年重新回到科研与实践当中。我将主要从以下几个方面着手,继续深化与拓展:
- 深化对 eBPF 的理解与研究
我会结合具体的场景,比如网络安全、可观测性、微服务治理等,探究 eBPF 在极端规模(大流量或复杂网络拓扑)下的优势和挑战。并且尝试与其他新兴技术结合,看是否能拓展更多的应用形态。 - 探索 WASM 在云端与边缘的应用
我想亲手实验一些基于 WASM 的函数计算平台,把它们与容器技术进行横向对比,看看不同的部署环境、不同的语言绑定,会给性能、扩展性和可维护性带来怎样的差异,也希望在这个过程中能摸索出更优的实践方案。 - 关注 CXL 对新一代数据中心与 HPC 的影响
虽然对硬件层面还不算太熟悉,但我会持续关注社区和行业的一些新动向,尽可能在底层架构优化或资源管理的角度上学习 CXL 能带来的新机遇。如果有机会,也希望与志同道合的团队一起做一些实验性的项目,验证 CXL 在实际应用中的价值和限制。 - 加强学术与工业界的连接
我会继续思考是否要在学术研究上投入更多时间,比如考虑读博士,或者在高校、研究机构里担任研究助理;同时也可能会到工业界或者开源社区参与实习或短期项目。这些都是为了能够将理论与实践更好地结合,让研究问题与真实需求互相促进、共同进步。 - 保持对身体健康的关注
病痛教会我,只有保持健康,我们才能够持续地投入到我们热爱的事情上。所以,在忙碌的科研与工作之外,我也会花更多的时间休息、运动、调节心态,让自己在追逐梦想的同时,不至于因为身体等因素而再次中断。
五、结语
回顾这一年,虽然从五月到十二月有相当长的一段时间被疾病困扰,但我觉得自己反而从中得到了更多关于人生与未来的启示。我更加明确:我真正的热爱与动力,还是源自对世界的好奇,对技术与创新的热情。无论未来做学术、做工业还是做开源,乃至于探索更多可能性,最重要的是不要失去那份“想玩的开心、想探索未知”的初心。
感谢大家在这一年里对我的关注、陪伴和帮助,也谢谢每一位给我提供技术指导和生活支持的朋友们。明年,希望我可以在 eBPF、WASM、CXL 等方向上取得更多进步,也期待能与更多有同样好奇心和热情的小伙伴们携手前行,在这个快速变化的时代,一起去创造新的可能性。
祝愿大家在新的一年身体健康、万事顺遂,也祝我们每个人都能继续保持对世界的好奇和探索的勇气。让我们一起迎接下一个更具挑战与机会的2025年!
谢谢大家!
C++ coroutine segfault for assigning into a shared object
struct Task {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type {
auto get_return_object() {
return Task{handle_type::from_promise(*this)};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() { }
void unhandled_exception() {}
};
handle_type handle;
Task(handle_type h) : handle(h) {}
~Task() {
if (handle) handle.destroy();
}
Task(const Task&) = delete;
Task& operator=(const Task&) = delete;
Task(Task&& other) : handle(other.handle) { other.handle = nullptr; }
Task& operator=(Task&& other) {
if (this != &other) {
if (handle) handle.destroy();
handle = other.handle;
other.handle = nullptr;
}
return *this;
}
bool done() const { return handle.done(); }
void resume() { handle.resume(); }
};
Task process_queue_item(int i) {
if (!atomicQueue[i].valid) {
co_await std::suspend_always{};
}
atomicQueue[i].res = remote1(atomicQueue[i].i, atomicQueue[i].a, atomicQueue[i].b);
}
why line atomicQueue[i].res = ... cause segfault?
Coroutine lifetime issues: If the coroutine is resumed after the atomicQueue or its elements have been destroyed, this would lead to accessing invalid memory.
solusion
Task process_queue_item(int i) {
if (i < 0 || i >= atomicQueue.size()) {
// Handle index out of bounds
co_return;
}
if (!atomicQueue[i].valid) {
co_await std::suspend_always{};
}
// Additional check after resuming
if (!atomicQueue[i].valid) {
// Handle unexpected invalid state
co_return;
}
try {
atomicQueue[i].res = remote1(atomicQueue[i].i, atomicQueue[i].a, atomicQueue[i].b);
} catch (const std::exception& e) {
// Handle any exceptions from remote1
// Log error, set error state, etc.
}
}
MOAT: Towards Safe BPF Kernel Extension
MPK only supports up to 16 domains, the # BPF could be way over this number. We use a 2-layer isolation scheme to support unlimited BPF programs. The first layer deploys MPK to set up a lightweight isolation between the kernel and BPF programs. Also, BPF helper function calls is not protected, and can be attacked.
- They use the 2 layer isolation with PCID. In the first layer, BPF Domain has protection key permission lifted by kernel to do corresponding work, only exception is GDT and IDT they are always write-disabled. The second layer, when a malicious BPF program tries to access the memory regions of another BPF program, a page fault occurs, and the malicious BPF program is immediately terminated. To avoid TLB flush, each BPF program has PCID and rarely overflow 4096 entries.
- helper: 1. protect sensitive objects It has critical object finer granularity protection to secure. 2. ensure the validity of the parameters. It(Dynamic Parameter Auditing (DPA)) leverages the information obtained from the BPF verifier to dynamically check if the parameters are within their legitimate ranges.
LibPreemptible
uintr come with Sapphire Rapids,(RISCV introduce N extension at 2019) meaning no context switches compared with signal, providing lowest IPC Latency. Using APIC will incur safety concern.
uintr usage
- general purpose IPC
- userspace scheduler(This paper)
- userspace network
- libevent & liburing
syscall addication(eventfd like) sender initiate and notify the event and receiver get the fd call into kernel and senduipi back to sender.
They wrote a lightweight runtime for libpreemptible.
- enable lightweight and fine grained preemption
- Separation of mechanism and policy
- Scability
- Compatibility
They maintained a fine-grained(3us) and dynamic timers for scheduling rather than kernel timers. It can greatly improve the 99% tail latency. Normal design of SPR's hw feature.
Reference
OMB-CXL: A Micro-Benchmark Suite for Evaluating MPI Communication Utilizing Compute Express Link Memory Devices
This paper talks about Message Passing Interface (MPI) libraries utilize CXL for inter-node communication.
In the HH case, CXL has lower latency than Ethernet for the small message range with 9.5x speedup. As the message size increases, the trend reverses with Ethernet performing better in latency than CXL due to the CXL channel having lower bandwidth than Ethernet in the emulated system 2 compute node with memory expander for each node.
Zero-NIC @OSDI24
Zero-NIC proactively seperate the control flow and datapath, it wplit and merge the headers despite reordering, retransmission and drops of the package.
It will send the payload to arbitrary devices with zero-copy data transfer.
It maps the memory into object list called Memroy Segment and manage the package table using Memory Region table. it will use IOMMU for address translation to host application buffer. Since the control stack is
co-located with the transport protocol, it directly invokes it
without system calls. The speed up is more like iouring to avoid syscalls. For scalability, MR can resides any endpoint.
It has the slightly worse performance than RoCE, while bringing TCP and higher MTU.