我正在创建一个多维向量(数学向量),我允许基本的数学运算,–,/,*,=.模板接受两个参数,一个是类型(int,float等),另一个是向量的大小.目前我通过for循环应用操作.现在考虑在编译时已知大小,编译器是否会展开循环?如果没有,有没有办法在没有(或最小)性能损失的情况下展开它?
template <typename T,u32 size> class Vector { public: // VarIoUs functions for mathematical operations. // The functions take in a Vector<T,size>. // Example: void add(const Vector<T,size>& vec) { for (u32 i = 0; i < size; ++i) { values[i] += vec[i]; } } private: T values[size]; };
在有人评论Profile然后优化之前请注意,这是我的3D图形引擎的基础,它必须很快.其次,我想知道为了教育自己.
解决方法
您可以通过反汇编执行以下技巧,以查看特定代码的编译方式.
Vector<int,16> a,b; Vector<int,65536> c,d; asm("xxx"); // marker a.Add(b); asm("yyy"); // marker c.Add(d); asm("zzz"); // marker
现在编译
gcc -O3 1.cc -S -o 1.s
并看到痉挛
xxx # 0 "" 2 #NO_APP movdqa 524248(%rsp),%xmm0 leaq 524248(%rsp),%rsi paddd 524184(%rsp),%xmm0 movdqa %xmm0,524248(%rsp) movdqa 524264(%rsp),%xmm0 paddd 524200(%rsp),524264(%rsp) movdqa 524280(%rsp),%xmm0 paddd 524216(%rsp),524280(%rsp) movdqa 524296(%rsp),%xmm0 paddd 524232(%rsp),524296(%rsp) #APP # 36 "1.cc" 1 yyy # 0 "" 2 #NO_APP leaq 262040(%rsp),%rdx leaq -104(%rsp),%rcx xorl %eax,%eax .p2align 4,10 .p2align 3 .L2: movdqa (%rcx,%rax),%xmm0 paddd (%rdx,(%rdx,%rax) addq $16,%rax cmpq $262144,%rax jne .L2 #APP # 38 "1.cc" 1 zzz
如您所见,第一个循环足够小,可以展开.第二个是循环.