【问题标题】:Using C++ function templates for a group of functions为一组函数使用 C++ 函数模板
【发布时间】:2015-12-02 05:53:05
【问题描述】:

根据从 8x8 到 20x20 的矩阵大小,我有不同的方阵乘法函数。这些函数彼此不同,因为每个函数都采用不同的优化策略,即不同的循环排列和不同的循环展开因子。矩阵大小在程序的生命周期内是不变的。我的目标是减少决定必须使用哪个功能的时间。例如,一个简单的实现是:

 if (matrixSize == 8) C = mxm8(A, B);
 else if (matrixSize == 9) C = mxm9(A,B);
 ...
 else if (matrixSize == 20) C = mxm20(A,B);

在这种情况下,决定每次矩阵乘法使用哪个函数所花费的时间是非常重要的。是否可以立即调用适当的函数,或者使用 C++ 函数模板?

【问题讨论】:

  • 如果matrixSize 是编译时常量,那么我完全期望优化编译器在编译时选择分支,并生成相当于单个函数调用的机器代码。如果matrixSize 不是编译时常量,那么模板无论如何也无济于事——在运行时不必进行分支。
  • The time taken to decide which function to use for every matrix multiplication is non-trivial in this case. 恕我直言,我觉得这很难相信。你有没有在非调试优化的构建上实际测量过这个时间?
  • 谢谢。我认为矩阵大小可以作为编译时间常数,因为与运行时间相比,编译时间可以忽略不计。尽管我没有测量分支的时间,但我可以看到当在我的应用程序中有大量调用此函数时它很受欢迎 - 100,000 甚至更多。
  • 如果它不是编译时间常数,那么改变逻辑以使用 switch 语句可能会有所帮助 - 尽管一个好的优化编译器可能会以与 switch 相同的方式优化上述内容。
  • 在最简单的情况下:创建一个全局变量Matrix (*mxm)(Matrix, Matrix)(调整类型以适应口味)。一旦知道大小,设置mxm指向对应的函数;你只会分支一次。之后,只需拨打mxm

标签: c++ templates if-statement optimization


【解决方案1】:

如果矩阵大小在程序的生命周期内是不变的,那么您可以使用std::array 中的std::array 作为矩阵类型。然后你可以有一个乘法函数并为你支持的不同类型重载它,并且选择将在编译时完成。

如果您为矩阵使用一些自定义类,您可以调整这种方法,并将其设置为模板类,其中大小是模板参数。

【讨论】:

    【解决方案2】:

    如果矩阵大小在编译时是已知的,你可以有类似的东西:

    constexpr auto matrixSize = 8;
    C = mxm<matrixSize>(A, B);
    

    并为任何已知大小提供专业化。

    如果您在编译时不知道大小,则无论如何都可以将函数存储在映射中,如下所示:

    map<size_t, function<matrix (const matrix&, const matrix&>> multipliers;
    multipliers.insert(make_pair(8, mxm8));
    

    然后使用类似的东西:

    C = multipliers[matrixSize](A, B);
    

    【讨论】:

    • 谢谢。使用地图也是一个好主意。比 if-then-else 块快得多,并且消除了编译时间选项的约束。
    • @Tania,实际上使用 unordered_map 应该更快。
    • @Tania:我认为地图实际上会比 if-else 块慢,因为它涉及动态分配。您可以使用 switch-case 构造来代替映射,这通常会被编译器优化为跳转表,这比这里的映射更好。
    • 感谢 Chris 的洞察力。
    • @ChrisBeck 虽然我同意您的评论,但维护 if-else 块可能会在以后变得令人头疼。有一个地方来初始化地图并在那里添加东西更简单恕我直言。
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多