我正在尝试分析类似于 David Vandevoorde 的“C++ 模板”一书中的表达式模板。下面是我的理论分析,这可能是错误的,因为测试显示了意想不到的结果。假设测试是关于:
R = A + B + C;
其中 A、B、C、R 是在堆上分配的数组。数组的大小为 2。因此将执行以下操作:
R[0] = A[0] + B[0] + C[0]; // 3 loads + 2 additions + 1 store
R[1] = A[1] + B[1] + C[1];
大约有 12 条指令(每条指令 6 条)。
现在,如果启用了表达式模板(显示在最底部),在编译器时进行类型推导后,将在运行时处理以下内容,然后执行与上述相同的评估:
A + B --> expression 1 // copy references to A & B
expression 1 + C --> expression 2 // copy the copies of references to A & B
// + copy reference to C
因此,在评估之前总共有 2+3=5 条指令,约占总指令的 5/(5+12)=30%。所以我应该能够看到这种开销,尤其是当向量大小很小的时候。
但结果表明,两者的成本几乎相同。我将测试迭代 1E+09 次。当然,两者的汇编代码是相同的。但是我找不到这个“构造”部分需要花费任何时间或说明的部分。
movsdq (%r9,%rax,8), %xmm0
addsdq (%r8,%rax,8), %xmm0
addsdq (%rdi,%rax,8), %xmm0
movsdq %xmm0, (%rcx,%rax,8)
我没有良好的CS背景,所以这个问题可能很愚蠢。但是这几天我一直在摸不着头脑。因此,任何帮助都是值得的!
--- 我的表情模板 ---
template< typename Left, typename Right >
class V_p_W // stands for V+W
{
public:
typedef typename array_type::value_type value_type;
typedef double S_type;
typedef typename traits< Left >::type V_type;
typedef typename traits< Right >::type W_type;
V_p_W ( const Left& _v, const Right& _w ) : V(_v), W(_w)
{}
inline value_type operator [] ( std::size_t i ) { return V[i] + W[i]; }
inline value_type operator [] ( std::size_t i ) const { return V[i] + W[i]; }
inline std::size_t size () const { return V.size(); }
private:
V_type V;
W_type W;
};
其中,traits 什么都不做,只是决定是否应该采用对象的引用值。例如,值是为整数复制的,但引用是为数组获取的。