调试中的向量数学库代码生成 · Aras 的网站

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]且已合并。
阅读 12
0 条评论