Как использовать умножение и накопить intrinsics в Коре-a8 ARM?

как использовать Умножение - Накапливают intrinsics, обеспеченный GCC?

float32x4_t vmlaq_f32 (float32x4_t , float32x4_t , float32x4_t);

Может любой объяснять, что три параметра я должен передать этой функции. Я имею в виду Источник и целевые регистры и что возвращает функция?

На помощь!!!

13
задан HaggarTheHorrible 13 July 2010 в 18:56
поделиться

2 ответа

Проще говоря, инструкция vmla выполняет следующее:

struct 
{
  float val[4];
} float32x4_t


float32x4_t vmla (float32x4_t a, float32x4_t b, float32x4_t c)
{
  float32x4 result;

  for (int i=0; i<4; i++)
  {
    result.val[i] =  b.val[i]*c.val[i]+a.val[i];
  }

  return result;
}

И все это компилируется в одну инструкцию ассемблера: -)

Вы можете использовать этот встроенный НЕОН-ассемблер среди прочего в типичных умножениях матриц 4x4 для 3D-графики вот так:

float32x4_t transform (float32x4_t * matrix, float32x4_t vector)
{
  /* in a perfect world this code would compile into just four instructions */
  float32x4_t result;

  result = vml (matrix[0], vector);
  result = vmla (result, matrix[1], vector);
  result = vmla (result, matrix[2], vector);
  result = vmla (result, matrix[3], vector);

  return result;
}

Это сэкономит пару циклов, потому что вам не нужно складывать результаты после умножения. Сложение используется так часто, что hsa с умножением становится в наши дни широко распространенным явлением (даже x86 добавила их в недавний набор инструкций SSE).

Также стоит упомянуть: подобные операции умножения-накопления очень распространены в приложениях линейной алгебры и DSP (цифровой обработки сигналов). ARM был очень умен и реализовал fast-path внутри Cortex-A8 NEON-Core. Этот быстрый путь срабатывает, если первый аргумент (аккумулятор) инструкции VMLA является результатом предыдущей инструкции VML или VMLA. Я мог бы вдаваться в подробности, но вкратце такая серия инструкций выполняется в четыре раза быстрее, чем серия VML / VADD / VML / VADD.

Взгляните на мою простую матрицу умножения: я сделал именно это. Благодаря такому быстрому пути он будет работать примерно в четыре раза быстрее, чем реализация, написанная с использованием VML и ADD вместо VMLA.

20
ответ дан 1 December 2019 в 20:42
поделиться

Google'd для vmlaq_f32 , обнаружил справочник по инструментам компилятора RVCT . Вот что он говорит:

Vector multiply accumulate: vmla -> Vr[i] := Va[i] + Vb[i] * Vc[i]
...
float32x4_t vmlaq_f32 (float32x4_t a, float32x4_t b, float32x4_t c);

И

Следующие типы определены для представления векторов. Типы векторных данных NEON именуются по следующему шаблону: <тип> <размер> x <количество полос> _t Например, int16x4_t - это вектор, содержащий четыре полосы, каждая из которых содержит 16-битное целое число со знаком. В таблице E.1 перечислены типы векторных данных.

IOW, возвращаемое значение из функции будет вектором, содержащим 4 32-битных числа с плавающей запятой, и каждый элемент вектора вычисляется путем умножения соответствующих элементов b и c ] и добавление содержимого a .

HTH

8
ответ дан 1 December 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: