ARM Assembler NEON - Повышение производительности - PullRequest
3 голосов
/ 23 февраля 2012

Я преобразовал часть алгоритма из C в ARM Assembler (используя инструкции NEON), но теперь он в 2 раза медленнее, чем исходный код C.Как мне улучшить производительность?

Цель - ARM Cortex-A9.

Алгоритм считывает 64-битные значения из массива.Из этого значения извлекается один байт, который затем используется в качестве значения поиска для другой таблицы.Эта часть выполняется примерно 10 раз, и каждое результирующее значение таблицы XOR´d, а остальные результаты записываются в другой массив.

Примерно так:

result[i] = T0[ GetByte0( a[i1] ) ] ^ T1[ GetByte1( a[i2] ) ] ^ ... ^ T10[ (...) ];

В моемподход Я загружаю весь массив «а» в неоновых регистрах, а затем переместить правый байт в регистр руки, вычислить смещение и затем загрузить значение из таблицы:

vldm.64 r0, {d0-d7}         //Load 8x64Bit from the input array

vmov.u8 r12, d0[0]          //Mov the first Byte from d0 into r12
add r12, r2, r12, asl #3    // r12 = base_adress + r12 << 3
vldr.64 d8, [r12]           // d8 = mem[r12]
.
.
.
veor d8, d8, d9             // d8 = d8 ^ d9
veor d8, d8, d10            // d8 = d8 ^d10      ...ect.

Где r2 содержит базовый адрестаблицы поиска.

adress = Table_adress + (8* value_fromByte);

Этот шаг (за исключением загрузки в начале) выполняется как 100 раз.Почему это так медленно?

Кроме того, каковы различия между "vld" , "vldr" и "vldm" - и которыеодин самый быстрый.Как я могу выполнить расчет смещения только в неоновых регистрах?Спасибо.

Ответы [ 4 ]

3 голосов
/ 24 февраля 2012

Неон не очень способен справляться с поисками, размер которых превышает пределы инструкции VTBL (32 байт, если я правильно помню).
Как создается таблица поиска для начала?Если это просто расчеты, просто позвольте Неону делать математику, а не прибегать к поиску.Так будет намного быстрее.

2 голосов
/ 23 февраля 2012

не используйте

vmov.u8 r12, d0[0]

перемещение данных из регистра NEON в регистр ARM - худшее, что вы можете сделать.

Может быть, вы должны увидеть инструкцию VTBL! Какой у вас диапазон байтов 0..255?

1 голос
/ 23 февраля 2012

Может быть, вы можете попробовать

ldrb     r12, [r0], #1
add      r3, r2, r12, asl #3
vld1.64  {d0}, [r3]

ldrb     r12, [r0], #1
add      r3, r2, r12, asl #3
vld1.64  {d1}, [r3]
veor     d0, d0, d1         // d8 = d8 ^ d1

ldrb     r12, [r0], #1
add      r3, r2, r12, asl #3
vld1.64  {d1}, [r3]
veor     d0, d0, d1         // d8 = d8 ^ d1

...

Это не будет лучшим решением. После этого вы можете повысить производительность, переупорядочив инструкцию.

0 голосов
/ 24 февраля 2012

Попробуйте это с NEON "intrinsics".По сути, это функции C, которые компилируются в NEON инструкции.Компилятор все еще выполняет все планирование команд, а другие скучные вещи (перемещающиеся данные) вы получаете бесплатно.

Это не всегда работает идеально, но это может быть лучше, чем пытаться передать кодэто.

Ищите arm_neon.h.

...