我现在有两个函数A和B。
在没有任何标志的情况下编译时,A比B快。
但在用-O1或-O3编译时,B比A快得多。
我希望将函数移植到其他语言,因此A似乎是一个更好的选择。
但是,如果我能够理解-O3如何能够加快B函数的速度,那就太好了。有什么好的方法至少可以稍微了解一下-O3所做的优化吗?
发布于 2019-08-17 15:09:31
-O3的功能与-O2相同,并且:
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
c[i][j] = c[i][j] + a[i][k]*b[k][j];被转换成
for (int i = 0; i < N; i++)
for (int k = 0; k < N; k++)
for (int j = 0; j < N; j++)
c[i][j] = c[i][j] + a[i][k]*b[k][j];for (int i = 0; i < n; ++i)
x[i * stride] = …;变成:
if (stride == 1)
for (int i = 0; i < n; ++i)
x[i] = …;
else
for (int i = 0; i < n; ++i)
x[i * stride] = …;例如,以下代码:
unsigned long apply(unsigned long (*f)(unsigned long, unsigned long), unsigned long a, unsigned long b, unsigned long c) {
for (unsigned long i = 0; i < b; i++)
c = f(c, a);
return c;
}
unsigned long inc(unsigned long a, unsigned long b) { return a + 1; }
unsigned long add(unsigned long a, unsigned long b) { return apply(inc, 0, b, a); }优化add函数以:
英特尔语法
add:
lea rax, [rsi+rdi]
retAT&T
add:
leaq (%rsi,%rdi), %rax
ret如果没有-O3输出,则为:
英特尔语法
add:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov QWORD PTR [rbp-16], rsi
mov rdx, QWORD PTR [rbp-8]
mov rax, QWORD PTR [rbp-16]
mov rcx, rdx
mov rdx, rax
mov esi, 0
mov edi, OFFSET FLAT:inc
call apply
leave
retAT&T
add:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -8(%rbp), %rdx
movq -16(%rbp), %rax
movq %rdx, %rcx
movq %rax, %rdx
movl $0, %esi
movl $inc, %edi
call apply
leave
ret您可以使用标志和-masm=intel比较函数A、和B的输出汇编程序。
这个答案是基于http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html的,你可以从中学到更多。
https://stackoverflow.com/questions/57536701
复制相似问题