реклама на сайте
подробности

 
 
> Графический фильтр на Cortex-M7, Увеличение ровно в 2 раза
__inline__
сообщение Jul 16 2018, 05:35
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Бьюсь над реализацией графического фильтра HQ2X на STM32H743 (Cortex-M7). Фильтр работает, но притормаживает, когда в кадре много мелких деталей.

Была предпринята оптимизация: Switch/Case из 256 значений был заменён на JumpTable. Не помогло. Исходный код фильтра (Keil ARM MDK):

Прикрепленный файл  HQ2x.rar ( 8.36 килобайт ) Кол-во скачиваний: 21


Требуется растянуть кадр в 2 раза по обеим осям.

Есть другие фильтры Scale2x, SaI2x , LQ2x - с ними проблем нет, на STM32H743 они идут довольно шустро(написанные на C, без Asm-а).

Вот тут чувак заточил под NEON и DSP фильтр HQnX (что не годится для Cortex-M7): https://pyra-handheld.com/boards/threads/ru...sp.69047/page-5

Существуют ли аналогичные графические фильтры (в частности HQ 2x), оптимизированные на ассемблере для ядер ARM Cortex-M7?

Работа фильтра пояснена на рисунке:

Прикрепленное изображение


Сообщение отредактировал __inline__ - Jul 16 2018, 05:37
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
__inline__
сообщение Jul 17 2018, 09:01
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126



Проделал несколько экспериментов.

1) Переписал Diff на ARM ASM:

Код
static inline int Diff(u32 yuv1,u32 yuv2)
{
register u32 t,z;
__asm
{
  USUB8 t,yuv1,yuv2    // t=yuv1-yuv2
  USUB8 yuv2,yuv2,yuv1 // yuv2=yuv2-yuv1
  SEL   t,yuv2,t       // t=abs(yuv1-yuv2)
  MOV   yuv1,#YUVMASK  // yuv1=YUVMASK
  MOV   z,#0           // z=0
  USUB8 yuv2,yuv1,t    // yuv2=YUVMASK-abs(yuv1-yuv2)
  SEL   yuv1,z,yuv1    // yuv1=(YUVMASK>=abs(yuv1-yuv2))?0:YUVMASK
}
return yuv1;
}


Фильтр работает, причем быстрее, чем с Си-шной реализацией Diff().

2) Сравнил быстродействие фильтра с вариантом JumpTable и Case/Switch. Как это ни странно, вариант с Case/Switch быстрее! Оптимизация Keil CC : -O3 -Otime.

Приемлемость работы фильтра оцениваю по косвенному признаку: задержки обновления кольцевого буфера DMA для воспроизведения звука - если звук хрипит, значит данные не успевают обновляться, значит фильтр нужно ещё более оптимизировать!

С фильтрами SaI, LQ2x, Scale2x звук не хрипит.

3) Возникла идея откомпилировать код фильтра на GCC и полученный объектник подстыковать к Keil. Думал, что невозможно, а оказалось - возможно!

Откомпилировал фильтр GCC тулчейн arm-eabi-gcc6.2.0-r4.exe :
Код
C:\arm-eabi\bin\arm-eabi-gcc.exe -fshort-wchar -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -O3 -Ofast -c -I ../Port HQ2x.cpp -o HQ2x.obj


Построил либу для Кейла:
Код
C:\arm-eabi\bin\arm-eabi-ar.exe cru HQ2x.lib HQ2x.obj


и подстыковал её в проект Keil.

Результаты приятно удивили - звук идёт ровно без лагов, фильтр работает!

Выходит, что GCC лучше заоптимизировал?

Ещё заметил, что ASM-листинг, даваемый компилятором Keil какой-то избыточный. А в GCC листинг достаточно прозрачен : применение инструкций вполне очевиден.

Связано ли это с тем, что Keil таблеточный? И производитель делает флуд АСМ-инструкций в генерируемый код в случае таблетки?

4) Вернул JumpTable вместо Case/Switch и скомпилировал в GCC. Результаты лучше, чем с Keil, но и тут Case/Switch также победил.

5) Заменил своппинг байтов на аппаратный:

Код
//#define rev16(x) (((x)>>8)|((x)<<8))

static u32 inline rev16(u32 x)
{
asm(
     "rev16 %[value],%[value]"

     : [value] "+r" (x)
     :
     : "cc"
    );

return x;
}


Стало ещё лучше - в GCC. А вот в Keil - наоборот было хуже. Это странно.

Асм-листинг в GCC смотрю:
Код
C:\arm-eabi\bin\arm-eabi-gcc.exe -fshort-wchar -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -O3 -Ofast -S -I ../Port HQ2x.cpp -o HQ2x.S


А теперь вопросы, попрошу ответить на них:

1) Можно ли в GCC выставить ещё более сильные флаги оптимизации по скорости, кроме тех что есть -O3 - Ofast ?

2) Оправдан ли переход на более новую версию тулчейна GCC с целью получить более производительный код?

3) Может ли ядро Cortex-M7 посчитать интерполяцию быстрее. Такого типа:

Код
pixel =( (pixel1 * 3) +  pixel2) / 4


где pixel - это пиксели 0:8:8:8 bit 0:R:G:B

4) Спуфит ли Keil лишними ASM-инструкциями для намерянного снижения производительности в вылеченных версиях?

5) Хочется избавиться от байт-своппинга REV16. Необходимость продиктована использованием DMA - дисплей требует занос старшего байта вначале, что приводит к некорректному отображения цвета (так как DMA передаёт вначале младший байт по дефолту).

6) В STM32H743 есть Master DMA и битовое поле Little/Big endianess для байтов/полуслов/слов. Но он у меня не заработал (трансфер Memory to Peripheral). А должен ли?

Рабочий код фильтра прикрепляю (и батник для сборки либы для Keil-ы под GCC ):

Прикрепленный файл  HQ2x_GCC_Opt_SRC.rar ( 33.59 килобайт ) Кол-во скачиваний: 11


Цитата(jcxz @ Jul 17 2018, 07:17) *
Кстати - по этой найденной Вами ассемблерной Diff() уже видно как значительно можно выиграть, написав весь блок вызовов Diff() в виде асм-функции и заинлайнив туда саму Diff(). Из неё сразу выпадают:
Код
  mov tmp2,#0                // tmp2 = 0
  movw value1,#0x0706
  movt value1,#0x30          // value1 = 0x300706
Которые запросто выносятся за рамки цикла. И вызовов/возвратов не нужно.


Попытаюсь осмыслить Вами сказанное и испытать.

Цитата(jcxz @ Jul 16 2018, 19:30) *
По идее можно попробовать написать просто: MOV Rx, #0x300706. Такой команды конечно нет, но некоторые трансляторы умные и заменяют такое на требуемую последовательность команд, возможно - наиболее оптимальную по их мнению.

Проверил: GCC делает 2 MOV, а Keil - LDR память

Сообщение отредактировал __inline__ - Jul 17 2018, 09:09
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- __inline__   Графический фильтр на Cortex-M7   Jul 16 2018, 05:35
- - Genadi Zawidowski   А попорбовать вместо ассемблерных вставок (которые...   Jul 16 2018, 06:12
|- - __inline__   Цитата(Genadi Zawidowski @ Jul 16 2018, 07...   Jul 16 2018, 07:49
- - ViKo   Рисунок врет. Например, глаза лягушонка он размыл ...   Jul 16 2018, 07:26
|- - aaarrr   Цитата(ViKo @ Jul 16 2018, 10:26) Рисунок...   Jul 16 2018, 07:49
||- - ViKo   Цитата(aaarrr @ Jul 16 2018, 10:49) Прост...   Jul 16 2018, 07:54
|- - __inline__   Цитата(ViKo @ Jul 16 2018, 08:26) Рисунок...   Jul 16 2018, 07:54
|- - KnightIgor   Цитата(__inline__ @ Jul 16 2018, 08:54) Н...   Jul 16 2018, 11:54
|- - __inline__   Цитата(KnightIgor @ Jul 16 2018, 12:54) О...   Jul 21 2018, 09:26
|- - Arlleex   Цитата(__inline__ @ Jul 21 2018, 12:26) В...   Jul 21 2018, 10:13
|- - __inline__   Цитата(Arlleex @ Jul 21 2018, 11:13) А за...   Jul 21 2018, 10:41
- - Genadi Zawidowski   CMSIS обычно подключен через соответствующий проце...   Jul 16 2018, 07:53
- - jcxz   Цитата(__inline__ @ Jul 16 2018, 08:35) Б...   Jul 16 2018, 08:00
|- - __inline__   Цитата(jcxz @ Jul 16 2018, 09:00) Уже пис...   Jul 16 2018, 08:07
|- - jcxz   Цитата(__inline__ @ Jul 16 2018, 11:07) П...   Jul 16 2018, 08:17
- - AVI-crak   Цитата(__inline__ @ Jul 16 2018, 11:35) В...   Jul 16 2018, 08:35
- - Genadi Zawidowski   Там тоже ассемблер с "неоном". Неон умее...   Jul 16 2018, 08:39
|- - jcxz   Я так понимаю - Вы сами пытались оптимизировать фу...   Jul 16 2018, 08:50
|- - __inline__   Цитата(jcxz @ Jul 16 2018, 09:50) Я так п...   Jul 16 2018, 14:54
- - Obam   Т.к. кортекс-М умеет только команды Tumb-2, то заг...   Jul 16 2018, 15:52
|- - __inline__   Цитата(Obam @ Jul 16 2018, 16:52) Т.к. ко...   Jul 16 2018, 16:21
|- - jcxz   Цитата(__inline__ @ Jul 16 2018, 19:21) Ч...   Jul 16 2018, 18:30
|- - jcxz   Кстати - по этой найденной Вами ассемблерной Diff(...   Jul 17 2018, 06:17
|- - __inline__   Цитата(jcxz @ Jul 17 2018, 07:17) Кстати ...   Jul 17 2018, 11:11
|- - jcxz   Цитата(__inline__ @ Jul 17 2018, 14:11) Е...   Jul 17 2018, 15:59
|- - __inline__   Цитата(jcxz @ Jul 17 2018, 16:59) Код in...   Jul 18 2018, 03:03
|- - jcxz   Цитата(__inline__ @ Jul 18 2018, 06:03) П...   Jul 18 2018, 08:57
|- - __inline__   Цитата(jcxz @ Jul 18 2018, 09:57) Я вообщ...   Jul 21 2018, 02:38
- - AVI-crak   Цитата(__inline__ @ Jul 17 2018, 15:01) 3...   Jul 17 2018, 15:26


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 17:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01502 секунд с 7
ELECTRONIX ©2004-2016