Преобразование короткого массива в плавающую точку с использованием ARM Neon - PullRequest
2 голосов
/ 18 октября 2011

Я только начал пытаться оптимизировать код Android с помощью NEON.У меня есть несколько проблем, однако.Основная проблема заключается в том, что я действительно не могу понять, как выполнить быстрое преобразование 16-разрядных в плавающие.

Я вижу возможность конвертировать несколько 32-разрядных целочисленных значений в плавающие в одной SIMD-инструкции, используя vcvt.s32.f32.Однако, как мне преобразовать набор из 4 S16 в 4 S32?Я предполагаю, что это как-то связано с инструкцией VUZP, но я не могу понять, как ...

Точно так же я вижу, что возможно использовать VCVT.s16.f32 для преобразования 1 16-битного в число с плавающей точкой привремя, но хотя это полезно, кажется очень расточительным не иметь возможности сделать это с помощью SIMD.

Я писал ассемблер на многих разных платформах на протяжении многих лет, но я нахожу документацию ARM совершенно непостижимой по некоторым причинам.

Как таковая, любая помощь будет по достоинству оценена.

Также есть ли способ получить показатели пропускной способности и задержки для устройства NEON?

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 18 октября 2011

Если никакие другие вычисления не должны выполняться вместе с преобразованием из 16-битного целого в 32-битное целое, вы можете перейти к uint32x4_t = vmovl_u16 (uint16x4_t)

Если перед преобразованием выполняется простое сложение или умножение и т. Д., Вы можете объединить их в одну инструкцию, например int32x4_t = vmull_u16 (int16x4_t, int16x4_t) или int32x4_t = vaddl_u16 (int16x4_t, int16x4_t) и т. д. и, таким образом, экономит некоторое количество циклов.

2 голосов
/ 18 октября 2011

Немного проработав мой комментарий: вы хотите "расширить" 4 16-разрядных регистра до 4 32-разрядных целых чисел перед преобразованием в 4 32-разрядных числа с плавающей запятой.Глядя на набор инструкций, я не думаю, что есть более быстрые пути преобразования, но я легко могу ошибаться.

Прямой метод заключается в использовании vaddl.s16 со вторым операндом из четырех нулей, но если выВы выполняете только преобразование, вы часто можете объединить преобразование с предыдущей операцией.Например, если вы умножаете два регистра int16x4, вы можете использовать vmull.s16, чтобы получить 32-битный вывод напрямую, а не сначала умножать и расширять позже (при условии, что вы не зависите от какого-либо усечения).

1 голос
/ 01 ноября 2011

зачем использовать циклы траты vaddl, инициализирующие ценный регистр с 0?

vmovl.s16 q0, d1

, а затем конвертировать q0

, что будет делать.

Мой вопрос:

  • Обязательно ли конвертировать их в плавающие?NEON намного быстрее выполняет целочисленные операции, чем float.(как выполнение, так и конвейер) Поэтому операции с фиксированной запятой в большинстве случаев будут более подходящими благодаря мощным длинным, широким, узким моделям в сочетании с арифметическими инструкциями и опциями автоматического округления / насыщения.

PS: странно, я думаю, что ARM PDF лучше всех.

...