返回首页
最新
今年早些时候,我花了一个月的时间重新审视我的编码习惯,并重新思考一些过去的设计选择。我希望在今年重写并改进我的开源软件库,但首先我需要对一些问题找到答案。也许这些问题会引起社区其他人的共鸣。
- 协程在高性能工作中是否可行?
- 我应该使用SIMD内建函数以提高可读性,还是直接使用汇编语言以便于库的分发?
- 硬件在AVX-512和SVE中的向量化散布/聚集方面是否已经跟上?
- 在Intel、Arm和AMD上,安全区和指针标记有什么不同?
- CPU和GPU张量核心(TCs)之间的吞吐量差距有多大?
- 不对齐的内存访问和分裂加载的成本有多高,非时间加载/存储能提供什么收益?
- 标准库的哪些部分对性能影响最大?
- 错误处理策略在开销上如何比较?
- 惰性求值范围的编译时间与运行时间之间的权衡是什么?
- 元编程有哪些实际的、非平凡的用例?
- 使用io_uring与POSIX套接字进行Linux内核绕过有多困难?
- 我们在有效使用C++的网络技术规范或异构执行器方面还有多远?
- 在嵌套容器中传播有状态分配器的最佳实践是什么,哪些库支持它们?
这些问题涵盖了从微内核优化(纳秒级)到分布式系统(微/毫秒延迟)的广泛主题。我没有打算在一篇文章中解决所有问题,而是将我的探索整理成一个代码库——扩展了我之前的Google Benchmark教程(<a href="https://ashvardanian.com/posts/google-benchmark" rel="nofollow">https://ashvardanian.com/posts/google-benchmark</a>)——作为性能实验的沙箱。
一些有趣的观察:
- 编译器现在能够很好地向量化3x3x3和4x4x4的单/双精度乘法!尽管操作数减少了70%,但较小的乘法仍然慢了约60%,超越了我原始的SSE/AVX,并且与AVX-512的性能差距在10%以内。
- Nvidia的张量核心在不同代之间在数值类型、吞吐量、瓦片形状、线程同步(线程/四元组/波/波组)和操作数存储方面差异显著。在Volta之后,通常需要手动编写PTX(因为内建函数滞后),不过新推出的TileIR(在GTC上介绍)承诺为密集线性代数内核带来改进。
- AI浪潮推动CPU和GPU在矩阵乘法的吞吐量和编程复杂性上趋于融合。我花了一天时间调试TMM寄存器初始化,SME同样奇怪。Sierra Forest每个插槽有288个核心,AVX10.2放弃了对256位的支持,转而支持512位……我在想,考虑到CPU的进步,独立的Intel GPU是否还真的有必要?
- 在常见的浮点范围内,标量正弦近似可以比标准实现快多达40倍,即使没有使用SIMD。不过这有点不够严谨;我希望更多项目能够记录误差范围,并提供像Sleef那样的1和3.5 ULP变体。
- 像CTRE这样的元编程工具可以比典型的正则表达式引擎快5倍,并且与手工编写的有限状态机相比,构建解析器的过程更为简单。
- 曾经在复杂性和性能上明显不同(DPDK/SPDK与io_uring),但现在差距正在缩小。虽然5.5版本之前的io_uring可以在回环IO上将UDP吞吐量提升4倍,但新的零拷贝和并发优化仍然具有挑战性。
这个代码库中包含了我最喜欢的CppCon讲座、GitHub代码片段和技术博客文章的链接。意识到许多高级概念在不同语言中的处理方式各异,我还开始将示例移植到Rust和Python的独立代码库中。协程在各个地方的表现都不太好 :(
总体而言,这个研究项目是非常有收获的!大多数问题在代码中找到了答案——除了指针标记和安全区,这两个问题在公共云中仍然困扰着我。我很想听听其他人的看法,特别是关于比较FPGA上小矩阵乘法的高级综合与手写的VHDL/Verilog在整数类型上的表现。如果你有其他有趣的、冷门的话题想要讨论,请告诉我!
您可以通过耳机或增强现实眼镜获得反馈。<p>您希望拥有这个功能吗?