GCC generuje wersję drugą, pewnie nie bez powodu.
Dodatkowo dokumentacja Intela wspomina, że instrukcje x87 mają dodatkowy narzut czasowy.
Jeśli możesz skorzystać SSE to proponowałbym wyrównać zmienne do 16 bajtów i użyć movdqa
.
Ale dlaczego chcesz w ogóle to optymalizować? Przy takiej ilości danych zauważalnej różnicy nie będzie. Chyba, że chcesz przenosić wiele takich long double
'i to napisz, bo to trochę zmienia postać rzeczy.
EDIT:
OK, zrobiłem benchmarki. Oto wyniki:
[bits 32]
[section .text]
[global main]
main:
mov ecx, 0xffffffff
l1:
fld tword [src]
fstp tword [dst]
loop l1
xor eax, eax
ret
[section .data]
src: dt 128.256
dst: dt 0.0
real 0m11.470s
user 0m11.408s
sys 0m0.000s
[bits 32]
[section .text]
[global main]
main:
mov ecx, 0xffffffff
l1:
mov eax, dword [src+0]
mov ebx, dword [src+4]
mov dx, word [src+8]
mov dword [dst+0], eax
mov dword [dst+4], ebx
mov word [dst+8], dx
loop l1
xor eax, eax
ret
[section .data]
src: dt 128.256
dst: dt 0.0
real 0m7.718s
user 0m7.720s
sys 0m0.000s
[bits 32]
[section .text]
[global main]
main:
mov ecx, 0xffffffff
l1:
mov esi, src
mov edi, dst
cld
movsd
movsd
movsw
loop l1
xor eax, eax
ret
[section .data]
src: dt 128.256
dst: dt 0.0
real 0m26.316s
user 0m26.328s
sys 0m0.000s
To mnie nieźle zaskoczyło.
[bits 32]
[section .text]
[global main]
main:
mov ecx, 0xffffffff
l1:
movdqa xmm0, [src]
movdqa [dst], xmm0
loop l1
xor eax, eax
ret
[section .data]
align 16
src: dt 128.256
align 16
dst: dt 0.0
align 16
real 0m6.388s
user 0m6.344s
sys 0m0.000s
Czyli wersja z SSE jest faktycznie najszybsza (przynajmniej na moim komputerze).