我要求C ++编译器生成一个机器编码函数,该函数对const std::vector
的元素求和。
#include <vector>
int sum(const std::vector<int>& v)
{
int s = 0;
for(const auto e:v) s += e;
return s;
}
我问编译器x86_64 GCC 7.2带有-O2
。它只是说:
sum(std::vector<int, std::allocator<int> > const&):
mov rdx, QWORD PTR [rdi]
mov rcx, QWORD PTR [rdi+8]
xor eax, eax
cmp rdx, rcx
je .L4
.L3:
add eax, DWORD PTR [rdx]
add rdx, 4
cmp rdx, rcx
jne .L3
rep ret
.L4:
rep ret
我对编译器Clang 4.0.0提出-O1
,-O2
和-O3
的问题。好!这是一篇完整的文章。它只是在-O1
,-O2
和-O3
的文章中操纵了一些形容词。
x86_64 ICC 17与-O2
和x86_64 CL 19类似。
然后我回到使用-O3
编译器x86_64 GCC 7.2。 x86_64 GCC 7.2现在提供了一个很长的输出。
答案 0 :(得分:2)
我认为你的问题是:
为什么会为这么简单的事情生成如此多的代码?
答案很长但是这样:
当我们操作内存时,现代内存架构可以实现更高的吞吐量......
因此,编译器试图通过尽可能地矢量化/并行化操作来优化长向量的情况,同时考虑到存储器架构的特性。
但并非所有向量都是可以作为块有效处理的项目数的倍数。
因此,矢量的开始和结束将通过特定操作单独处理,而(长)矢量的大部分由中间的智能矢量化代码处理。