我正在使用CRTP模式,并注意到MSVC 14(Visual Studio 2015 Update 1)无法优化(即使使用-O2)以下CRTP模式的开销。
RANK
GCC和Clang做得很好,生成的代码与手动生成的变量一样快,没有任何间接。但是,MSVC生成代码的运行时间明显变慢。如果我移除template <typename T, size_t N, typename Derived>
struct Base
{
__forceinline Derived& operator+=(const Derived &b)
{
return (static_cast<Derived&>(*this) = static_cast<Derived&>(*this) + b);
}
};
template <typename T, size_t N>
struct A: Base<T,N, A<T,N>>
{
T data[N];
};
template <typename T, size_t N>
__forceinline A<T, N> operator+(const A<T, N> &a, const A<T, N> &b)
{
A<T, N> result;
// just an unroll helper, because MSVC doesn't unroll small loops
unroll_for<0, N>([](size_t i)
{
result.data[i] = a.data[i] + b.data[i];
});
return result;
}
int main()
{
A <float,4> a;
A <float,4> b;
a += b;
return 0;
};
部分并手动将(static_cast<Derived&>(*this) = static_cast<Derived&>(*this) + b);
的主体内联到它的位置,则开销会消失,性能就是我所期望的。所以问题应该放在operator+
s。
我的CRTP演员中有什么问题,或者这又是MSVC的弱点吗?
修改
我包含一个可以使用简单计时器轻松测试的工作代码。
static_cast