Как добавить значения из вектора друг к другу

В моем коде я решаю интеграл

y=x^2-4x+6

Я использовал SSE — он позволяет мне работать с 4 значениями одновременно. Я сделал программу, которая решает этот интеграл со значениями от 0 до 5, разделенными на пять 4-элементных векторов n1, n2, n3, n4.

.data
n1: .float 0.3125,0.625,0.9375,1.25
n2: .float 1.5625,1.875,2.1875,2.5
n3: .float 2.8125,3.12500,3.4375,3.75
n4: .float 4.0625,4.37500,4.6875,5
szostka: .float 6,6,6,6
czworka: .float 4,4,4,4
.text
.global main
main:  
        movups (n1),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm7

        movups (n2),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm6

        movups (n3),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm5

        movups (n4),%xmm0

        mulps %xmm0,%xmm0
        movups (szostka),%xmm2
        addps %xmm2,%xmm0
        movups (n1),%xmm1
        movups (czworka),%xmm2
        mulps %xmm2,%xmm1
        subps %xmm1,%xmm0
        movups %xmm0,%xmm4

        mov $1,%eax
        mov $0,%ebx
        int $0x80 

В итоге у меня 4 вектора в регистрах xmm7, xmm6, xmm5, xmm4. Чтобы решить интеграл, мне нужно сложить векторы друг с другом (что несложно), а затем сложить значения из вектора также друг с другом.
Как мне это сделать?


person DzikiChrzan    schedule 08.06.2015    source источник
comment
Предполагая, что вы хотите добавить элементы по горизонтали, вы можете использовать haddps. Вам нужно вызвать его дважды, чтобы суммировать все 4 элемента.   -  person Paul R    schedule 09.06.2015
comment
Имейте в виду, что haddps требует поддержки SSE3.   -  person Chuck Walbourn    schedule 09.06.2015
comment
Так есть ли что-нибудь еще, что я мог бы сделать?   -  person DzikiChrzan    schedule 09.06.2015
comment
Вы говорите, что ваш процессор не имеет SSE3, то есть ему › 10 лет?   -  person Paul R    schedule 09.06.2015
comment
Йии нет! Честно говоря, я только начинаю читать об этом.   -  person DzikiChrzan    schedule 09.06.2015
comment
Да, это решает мою проблему. Спасибо, Павел Р!   -  person DzikiChrzan    schedule 09.06.2015


Ответы (1)


Как сказал Пол Р. в комментарии, вы можете использовать haddps для горизонтальных операций внутри вектора в конце.

Ваш код выглядит неэффективным. Если вы собираетесь полностью развернуться, вместо использования цикла и аккумулятора вы можете в первую очередь использовать разные регистры для каждой копии вместо того, чтобы иметь movups %xmm0,%xmmX в конце каждого блока.

Кроме того, сохраняйте (szostka) и (czworka) в регистре между итерациями. Не перезагружайте их каждый раз. Точно так же замените movups (n1),%xmm1 на movups %xmm0, %xmm1 (перед возведением в квадрат %xmm0). В IvyBridge и более поздних версиях этап переименования регистров обрабатывает перемещения регистров, и они происходят с нулевой задержкой.

Если вам нужно каждый раз загружать (szostka), лучше использовать addps с операндом памяти, а не отдельно перемещать и добавлять. Микросинтез мог бы сохранить эту операцию как единую операцию.

Посетите http://agner.org/optimize/, чтобы найти документы по оптимизации сборки. Возможно, вам будет полезнее использовать встроенные функции, чтобы позволить компилятору позаботиться о мелких деталях, таких как распределение регистров, вместо того, чтобы напрямую писать на ассемблере.

person Peter Cordes    schedule 25.06.2015
comment
На этот вопрос вам нужно ответить. - person Z boson; 06.07.2016
comment
@Zboson: спасибо за пинг. Я был в отъезде на несколько дней, чтобы навестить своего брата в Монктоне, чтобы посмотреть театральный ужин, в котором он участвует. - person Peter Cordes; 06.07.2016