У меня проблемы с пониманием определенного фрагмента кода в сборке.Задача состоит в том, чтобы найти скалярное произведение двух векторов, используя арифметику SSE и регистры XMM.Подход состоит в том, чтобы считывать векторы 4 с плавающей точкой за раз (то есть один регистр xmm будет содержать четыре за одну итерацию).Конечным результатом этого является регистр xmm, в котором каждый байт содержит сумму произведений (x1 * y1 + ...) заданных векторов.
То, что я не получаю, это часть, которая следует после.Все, что нужно для суммирования этих «конечных» байтов в целом, в основном составляет 4 байта, составляющих окончательный регистр.Я пытался найти что-то по этому поводу, но безуспешно.То, что мне дают, находится за пределами моего понимания, я даже пытался написать каждое вычисление на бумаге, ничего не имело особого смысла.В выделенной части фактическая сумма вычисляется и сохраняется в младшем байте xmm0
.Любое понимание этого приветствуется.
.intel_syntax noprefix
.data
two: .int 2
.text
.global dot_product
############################################################################
##
## Function:
##
## void dot_product(float *x, float *y, int n, float *r);
##
## calculates the dot product of x and y (n lengths) and stores the result
## in r
##
## -- float * x -- rdi --
## -- float * y -- rsi --
## -- int n -- rdx --
## -- float * r -- rcx --
##
############################################################################
dot_product:
enter 0, 0
mov r8, rcx
mov r9, rdx
mov rax, 1
cpuid
test rdx, 0x2000000
jz not_supported
mov rdx, rsp
and rsp, 0xfffffffffffffff0
sub rsp, 512
fxsave [rsp]
mov rcx, r9
xorps xmm0, xmm0
next_four:
cmp rcx, 4
jb next_one
movups xmm1, [rsi]
movups xmm2, [rdi]
mulps xmm1, xmm2
addps xmm0, xmm1
add rsi, 16
add rdi, 16
sub rcx, 4
jmp next_four
next_one:
jrcxz finish
movss xmm1, [rsi]
movss xmm2, [rdi]
mulss xmm1, xmm2
addss xmm0, xmm1
add rsi, 4
add rdi, 4
dec rcx
jmp next_one
finish:
#**summing the 4 bytes giving the actual dot product**
movhlps xmm1, xmm0
addps xmm0, xmm1
movaps xmm1, xmm0
shufps xmm1, xmm1, 0b01010101
addss xmm0, xmm1
movss [r8], xmm0
fxrstor [rsp]
mov rsp, rdx
done:
leave
ret
not_supported:
mov rax, 1
mov rbx, 1
int 0x80