Я начинаю с трех значений A, B, C (32-битное целое число без знака). И мне нужно получить два значения D, E (также 32-битное целое число без знака). Где
D = high(A*C);
E = low(A*C) + high(B*C);
Я ожидаю, что умножение двух 32-битных uint даст 64-битный результат. «Высокий» и «Низкий» - это просто мои обозначения для обозначения первых 32 бита и последних 32 бита в 64-битном результате умножения.
Я пытаюсь получить оптимизированный код какого-нибудь уже работающего. У меня есть короткая часть кода в огромном цикле, который состоит всего из нескольких командных строк, однако он занимает почти все вычислительное время (физическое моделирование для пары часов вычислений). Вот почему я стараюсь оптимизировать эту небольшую часть, а остальная часть кода могла бы оставаться более удобной для пользователя.
Есть несколько инструкций SSE, которые подходят для вычисления упомянутой процедуры. Компилятор gcc, вероятно, оптимизировал работу. Однако я не отвергаю возможность написать какой-то фрагмент кода напрямую в SSE, если это будет необходимо.
Пожалуйста, проявите терпение, учитывая мой низкий опыт работы с SSE. Попробую просто символически написать алгоритм для SSE. Возможно, будут ошибки при заказе масок или понимании структуры.
- Сохраните четыре 32-битных целых числа в одном 128-битном регистре по порядку: A, B, C, C.
- Применить инструкцию (вероятно, pmuludq) в упомянутый 128-битный регистр, которая умножает пары 32-битных целых чисел и в результате возвращает пары 64-битных целых чисел. Таким образом, он должен одновременно вычислять умножение
A*C
и умножениеB*C
и возвращать два 64-битных значения. - Я ожидаю, что у меня будут новые 128-битные значения регистров P, Q, R, S (четыре 32-битных блока), где P, Q - это 64-битный результат
A*C
и R, S - 64-битный результатB*C
. Затем я продолжаю переставлять значения в регистре в порядке P, Q, 0, R - Возьмите первые 64 бита P, Q и добавьте вторые 64 бита 0, R. Результат - новое 64-битное значение.
- Считайте первые 32 бита результата как D и последние 32 бита результата как E.
Этот алгоритм должен возвращать правильные значения для E и D.
Мой вопрос:
Есть ли в С ++ статический код, который генерирует подобную процедуру SSE, как упоминалось в алгоритме 1-5 SSE? Я предпочитаю решения с более высокой производительностью. Если алгоритм проблематичен для стандартных команд c ++, есть ли способ написать алгоритм в SSE?
Я использую 64-битный компилятор TDM-GCC 4.9.2.
(примечание: вопрос был изменен после совета)
(примечание 2: меня вдохновляет этот http://sci.tuomastonteri.fi/programming/sse для использования SSE для повышения производительности)
4294967296
равно1ull << 32
. - person Jarod42   schedule 02.02.2016uint64_t
кажется более простым и эффективным, чем альтернативы (например, умножение вручную сuint16_t
). - person Jarod42   schedule 02.02.2016low32(A*C) + high32(C*B)
. Итак, если вам просто нужны обе половины результат умножения 32b, используйте его. В любом случае, возможно, стоит векторизовать его, в зависимости от того, как выглядит окружающий код. Если вы намекнете об этом, возможно, мы сможем помочь вам векторизовать. Ваша версия этого документа до редактирования определенно была проблема XY - person Peter Cordes   schedule 03.02.2016