3

在我的代码的最新一轮重构中,我用可变参数对应物替换了一堆具有固定数量模板参数的模板类。我很困惑地发现一个特定的性能测试用例的性能下降了大约 20-30%。

几次 git bisect 往返之后,确定了有问题的提交。它实际上由一个单一的变化组成

template <typename T, typename U>
class foo {};

template <typename T, typename ... Args>
class foo {};

我已经通过实验证实,应用这个单一的改变会产生上面提到的减速。更令人费解的是,切换编译器版本(从 GCC 4.7 到 GCC 4.8)会将减速发生移动到另一个类似的提交(即,另一个从固定到可变参数的切换,但在不同的类中bar)。

为了提供一些背景信息,这个特定的性能测试用例是一个非常稀疏的计算机代数问题,它受内存限制,因此很容易受到有效缓存内存利用的影响。这个测试用例一直是我的代码中的一个问题点(例如,在 GCC 4.4/4.5 前后,我不得不手动调整管理缓存行大小检测的编译器选项,以获取最大性能)。

有没有人知道什么可能导致这种行为?不幸的是,我担心提取简化的测试用例可能非常困难。

编辑

作为参考,这是恢复良好性能行为的提交。不幸的是,它包括为一堆类(而不仅仅是一个类)恢复为非可变代码。我将尝试提出一个更有限的例子。

https://gitorious.org/piranhapp0x/mainline/commit/b952c613b42fe480fe4ed2dfd3e683eb9e38e4cd

4

1 回答 1

5

这是一个广泛的问题,通常的嫌疑人(就我而言)是在生成的代码中递归处理可变参数模板参数。

您需要检查现在使用可变参数模板参数的方法是否以递归仅在编译时发生的方式实现,而不是在运行时发生。为了给你一些想法,你可能想看看一些例子,例如,我的这个答案。递归发生在编译时,真正的代码是单步转发和扩展。

尽管你写了什么,但我确实希望你实际上必须修改一些代码,否则Args除了单个参数之外永远不能保存任何其他东西,并且拥有可变参数模板参数完全没有意义 - 如果我错了,请原谅我;) (根据您的评论,它可能会在您将参数包传递到的代码中触发类似上述内容)

于 2013-09-24T15:39:47.197 回答