2024 年 9 月 14 日发布,主要讨论在 C++代码中使用“向量数学库”时,代码风格的选择如何影响非优化构建性能。
- 背景:一个月前深入研究 Blender 代码库中图像缩放的各种方式,修复了一些函数的行为,使代码更快速且文档更完善,但使代码变小,主要遵循使用 C++数学库的准则,却导致 Blender 部分功能在非优化(“Debug”)构建中变慢,如保存文件时的截图缩放操作。
- Blender 的 C++数学库写法:结构紧凑整洁,通过模板和 lambda 实现向量运算,但存在断言导致 MSVC 在开发配置下运行变慢的问题。
- 测试案例:简单的图像处理代码,在不同编译器和优化级别下处理 512x512 输入图像的时间测试,Clang 在 Release 模式下表现较好,Debug 模式下各编译器性能差异大。
可采取的措施:
- 编译器添加的“-Og”优化级别可在一定程度上提高性能,如 Clang 和 gcc 在该级别下表现较好。
- 改变代码结构,如将 unroll + lambda 改为简单循环,可改善 Debug 配置的性能,但会影响 Gcc 的 Release 模式性能;显式为 2D/3D/4D 向量情况编写代码路径可大幅提升 Debug 配置性能,但需使用 C 预处理器宏。
- 回到 C 风格编写代码可使 Debug 构建性能良好,甚至在 Release 模式下 Clang 下比 C++代码快,说明 C++抽象并非零成本。
- 手动添加模板特化使用 SIMD intrinsics 在除 Clang 外的编译器的各种模式下都有性能提升,但在 Debug 构建中性能成本高。
- 在 gcc 上使用 -O3 优化级别可解决将 unroll lambda 改为简单循环的问题,在 Clang 上可使各种 C++方法接近“纯 C”或“SIMD”风格的性能。
- 在 MSVC 中“force inline”不可行,Clang 中的 force inline 属性帮助不大。
- 学习心得:Clang 在各种编码风格下代码速度最快;C++抽象并非零成本(除 Clang 外);Debug 构建性能差,可通过 C 预处理器宏专门化代码改善;MSVC Debug 构建性能并非极差;非优化构建中 SIMD intrinsics 性能差;可考虑使用“-Og”优化级别;Visual Studio 的“just my code debugging”性能成本高。所有测试代码在github 仓库,Blender 代码库的相关 PR 为[#127577]且已合并。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。