Marc:
I decided to compare the speed of a simple program to compute pi using the Chudnovsky's algorithm under two different configurations. The first is my usual one:
./configure 'CC=/usr/local/gcc-7.1.0/bin/gcc -march=native -D___CAN_IMPORT_CLIB_DYNAMICALLY' '--enable-single-host' '--enable-multiple-versions' '--enable-shared'
The second added
--enable-c-opt=-O2 --enable-gcc-opts --enable-gnu-gcc-no-strict-aliasing=no
I was pretty surprised at the difference in performance:
heine:~> ./chud2 (time (number->string (pi 1000000))) 3499 ms real time 3500 ms cpu time (3468 user, 32 system) 462 collections accounting for 89 ms real time (100 user, 0 system) 863430184 bytes allocated 47370 minor faults no major faults
for the first, and
heine:~> ./chud2 (time (number->string (pi 1000000))) 2604 ms real time 2604 ms cpu time (2560 user, 44 system) 462 collections accounting for 79 ms real time (76 user, 4 system) 863429856 bytes allocated 47360 minor faults no major faults
for the second. I was a bit surprised at the size of the difference.
The main loop of either the direct or the inverse FFT (I can't tell which at the moment) is translated to
.L5952: movq 32(%rsp), %rax leaq (%r9,%rbx), %rcx vmovsd (%rbx), %xmm1 leaq (%r9,%r11), %rsi vmovsd (%rcx), %xmm8 leaq (%rsi,%r9), %r8 leaq (%r9,%rcx), %rdi vmovsd (%rsi), %xmm10 movq %rax, 152(%rsp) leaq 0(%rbp,%r10), %rax vmovsd (%r11), %xmm9 leaq (%r9,%rdi), %r13 vsubsd %xmm8, %xmm1, %xmm7 vaddsd %xmm8, %xmm1, %xmm11 vmovsd (%rdi), %xmm4 vmovsd (%rdi), %xmm1 movq %rax, 168(%rsp) movq 32(%rsp), %rax vsubsd %xmm10, %xmm9, %xmm0 vaddsd %xmm10, %xmm9, %xmm10 vmovsd 7(%r12), %xmm13 vmovsd 15(%r12), %xmm12 addq $16, %rbx addq $16, %r11 addq %r10, %rax vsubsd 0(%r13), %xmm4, %xmm4 vaddsd 0(%r13), %xmm1, %xmm9 movq %rax, 88(%rsp) leaq 0(%rbp,%r9), %rax vmovsd (%r8), %xmm2 movq %rax, 184(%rsp) movq 88(%rsp), %rax addq %r10, %rax movq %rax, 80(%rsp) movq 120(%rsp), %rax addq %rbp, %rax addq $8, %rbp movq %rax, 128(%rsp) movq 80(%rsp), %rax addq %r10, %rax movq %rax, 192(%rsp) movq 136(%rsp), %rax vmovsd (%rax), %xmm3 movq 144(%rsp), %rax vmovsd (%rax), %xmm5 leaq (%r8,%r9), %rax vmovsd (%rax), %xmm6 movq %rax, 96(%rsp) vmovsd %xmm6, 72(%rsp) vsubsd 72(%rsp), %xmm2, %xmm2 vmovsd 72(%rsp), %xmm1 vmovapd %xmm5, %xmm6 vaddsd (%r8), %xmm1, %xmm8 vmulsd %xmm7, %xmm3, %xmm1 vxorpd %xmm15, %xmm6, %xmm6 addq $8, 32(%rsp) vfmadd231sd %xmm0, %xmm5, %xmm1 vmulsd %xmm0, %xmm3, %xmm0 vfnmadd231sd %xmm7, %xmm5, %xmm0 vmulsd %xmm4, %xmm6, %xmm5 vmovapd %xmm5, %xmm7 vsubsd %xmm8, %xmm10, %xmm5 vfmadd231sd %xmm2, %xmm3, %xmm7 vmulsd %xmm2, %xmm6, %xmm2 vmovapd %xmm3, %xmm6 vfnmadd132sd %xmm4, %xmm2, %xmm6 vsubsd %xmm9, %xmm11, %xmm4 vaddsd %xmm9, %xmm11, %xmm11 vsubsd %xmm7, %xmm1, %xmm2 vaddsd %xmm7, %xmm1, %xmm7 vmovsd %xmm11, -16(%rbx) vaddsd %xmm8, %xmm10, %xmm11 vsubsd %xmm6, %xmm0, %xmm3 vaddsd %xmm6, %xmm0, %xmm6 vmulsd %xmm5, %xmm13, %xmm0 vmovsd %xmm11, -16(%r11) vmovsd %xmm7, (%rcx) vmulsd %xmm4, %xmm13, %xmm7 vmovsd %xmm6, (%rsi) vfnmadd132sd %xmm12, %xmm0, %xmm4 vmulsd %xmm3, %xmm13, %xmm0 vfmadd231sd %xmm5, %xmm12, %xmm7 vmulsd %xmm2, %xmm13, %xmm5 vmovsd %xmm7, (%rdi) movq 96(%rsp), %rdi vmovapd %xmm5, %xmm7 vmovsd %xmm4, (%r8) vfmadd231sd %xmm3, %xmm12, %xmm7 vfnmadd132sd %xmm2, %xmm0, %xmm12 vmovsd %xmm7, 0(%r13) vmovsd %xmm12, (%rdi) cmpq %rbp, 48(%rsp) jg .L5952
Looking at the output of the scheduler, it seems like this loop, with 40 floating-point operations, was scheduled in 74 cycles. Not bad. With the original options it was schedule in 91 cycles.
Brad
Afficher les réponses par date