【发布时间】:2013-09-29 22:08:08
【问题描述】:
在我的代码的最新一轮重构中,我用可变参数对应物替换了一堆具有固定数量模板参数的模板类。发现一个特定的性能测试用例出现了大约 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
【问题讨论】:
-
真的是空班吗?还是只是简化?
-
@DavidRodríguez-dribeas:只是一个简化。我想明确一点,唯一的变化是切换到可变参数模板声明。其余代码保持不变,不知道类的可变参数和非可变参数版本之间的区别。
-
如果代码的其余部分保持“不变”,那不是每次有人说
U时都会中断吗? -
@KerrekSB:好点。在这种情况下,
Args被简单地传递给一个成员对象,该对象确实具有处理可变参数位的所有机制。打破一切的是顶级阶层的变化。 -
@bluescarni:所以变化不是只是上面那个,而是那个和使用可变参数的底层对象......正如你所说的那样,这个问题很糟糕,因为您在询问
{}和{}的性能差异,它们代表相似但不同的代码。 -1
标签: c++ templates gcc c++11 variadic-templates