SSE2 извлекает данные из упакованных данных в golang - PullRequest
0 голосов
/ 03 октября 2018

Я пишу функцию сборки на Голанге.Для упрощения предположим, что я хочу выполнить следующую функцию:

func sseSumOfMinimums (d1, d2 [2]float64) float64

Она вычислит минимум d1 [0], d2 [0] и минимум d1 [1] и d2 [1].и вычисляю сумму

В сборке я делаю:

TEXT ·sseSum(SB), $0-40
MOVUPD d1+0(FP), X0 // loading d1 to X0
MOVUPD d2+16(FP), X1 // loading d1 to X1
MINPD X0, X1 // compute pair minimums and store to X1
MOVSD X1, X2 // move first min to X2
// How do I move second float of X1 to X3?
ADDSD X2, X3
MOVSD X3, ret+32(FP)

Часть, которую мне не хватает, это как извлечь второй скаляр из X1 в X3

1 Ответ

0 голосов
/ 03 октября 2018

Go не гарантирует выравнивание стека, чтобы вы могли использовать операнд источника памяти для minpd?

Кроме того, я не знаком с Go;действительно ли это float двоичный код IEEE64, который большинство языков (включая x86 asm) называют double?Странно видеть float в исходном коде и pd (упакованные двойные) инструкции, используемые в asm.


Затраты на вызов автономной рукописной функции asm для этого будутбыть выше, чем позволить компилятору сделать это с помощью скаляра minsd для одной пары.Особенно в соответствии с дрянным соглашением о вызовах Go, передачей аргументов в памяти и сохранением возвращаемого значения в памяти.

Оптимизирующий компилятор Go с внутренним LLVM или gcc должен выполнять работу со встроенным кодом с меньшей задержкой и меньшим временем ожидания.мера стоимости пропускной способности, чем вызов этой функции, даже с оптимизацией, приведенной ниже.Или, если вам повезет, компилятор будет использовать minpd для вас.


Но для реальной проблемы после minpd x0, x1 вам понадобится горизонтальная сумма xmm1. Самый быстрый способ сделать горизонтальную векторную сумму с плавающей запятой на x86 .

Вы должны использовать movaps для копирования регистров xmm, даже если вы заботитесь только о младших 64 битах.movsd x1, x2 сливается с младшими 64 битами xmm2, создавая ложную зависимость от старого значения и стоя случайного шага.

minpd   x0, x1
movhps  x1, x0        // high 64 bits of xmm1  => low 64 of xmm0
addsd   x1, x0

Вы можете movaps x1, x2 и unpckhpd x2,x2, но это будет стоитьдополнительные movapd или movaps, которых можно избежать с помощью movhps.

(movaps / movups короче movapd, меньшего размера кода и в остальном точно эквивалентны movapd / movupd на всех процессорах для загрузки, хранения и reg-reg копий.)

...