Jump to content

    
GenaSPB

STM32MP1 - bare metal

Recommended Posts

On 12/21/2019 at 6:29 PM, GenaSPB said:

STM32H743

cplxmla @00000DED, src @24010E00, dst @24000E00. refv @20004220, CPU_FREQ=384 MHz

Тестовый выход - 969 Hz

 

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

У меня STM32H743 (@400MHz) выдает 1.018кГц (что пересчитывается с учетом частоты +- в тот же результат). Но всем кто когда-либо писал ЦОС алгоритмы для М7 должно быть известно, что циклы у них забирают сильно много ресурсов. Если развернуть цикл "на 8", то частота вырастает до 1.193кГц - 17% прироста однако ;).

Теперь про A9. Достал один старый проект (Cortex-A9@666MHz), всунул туда "тест", итак:

- массивы в DDR, максимум что вышло 1.63кГц

- два массива в SRAM, один в ДДР - 1.71кГц

Интересно, что последние версии GCC существенно проигрывают в производительности, может правда установки по-умолчанию отличаются - не заморачивался.

Еще один интересный момент - попытка развернуть цикл на А9 дала обратный эффект, причем очень сильный.

Для полной картины не хватает варианта оптимизированного руками под неон.

Share this post


Link to post
Share on other sites
56 minutes ago, Шаманъ said:

У меня STM32H743 (@400MHz) выдает 1.018кГц (что пересчитывается с учетом частоты +- в тот же результат). Но всем кто когда-либо писал ЦОС алгоритмы для М7 должно быть известно, что циклы у них забирают сильно много ресурсов. Если развернуть цикл "на 8", то частота вырастает до 1.193кГц - 17% прироста однако ;).

Теперь про A9. Достал один старый проект (Cortex-A9@666MHz), всунул туда "тест", итак:

- массивы в DDR, максимум что вышло 1.63кГц

- два массива в SRAM, один в ДДР - 1.71кГц

Интересно, что последние версии GCC существенно проигрывают в производительности, может правда установки по-умолчанию отличаются - не заморачивался.

Еще один интересный момент - попытка развернуть цикл на А9 дала обратный эффект, причем очень сильный.

Для полной картины не хватает варианта оптимизированного руками под неон.

интересно, почему loop unroll дал такой эффект у вас. Еще больше непонятно, что это у меня так А15 рванул то, он согласно вики только на 40% быстрее по IPC.

Ищу ошибку, ведь А53 торомзил так же , как и А8 и ничем не удивил. Память у всех +- ДДР3 800

Правда у А15 2.5 метра L3 ончипной

PS кое-что вроде проясняется. У А7 FPU pipelined, у А8 - нет, поэтому у Гены и А7 вероятно быстрее.

А у А15 - NEON на 128 бит размахнулся. Правда и с выключенным неоном как-то сильно скаканул. (но очень похоже, что делает две плавающих точки за такт супротив одной у всех остальных, включая А53)

Остается загадкой торомоза А53, из которого почему-то выкинули out-of-order , но я еще пока не разобрался что оно дает ))) 

Безымянный.png

 

А decode width это что? может 3 инструкции одновременно фигачить, если они не занимают нужных блоков в ядре? И вообще А53 судя по таблице каким-то шагом назад от А15 смотрится, декодер урезали, out of order убрали, pipeline правда, сократили что вроде и не хорошо и не плохо. (может сообразили, что у них армы в кипятильники превращаются , а там их 86ой кроет как бык овцу и ловить нечего?)

PS неболльшой unroll цикла пополам только замедлил на 5 % работу. Вероятно при таком длинном pipeline и BTP ему циклы не помеха.

 

PPS - нашел ошибку в тестах А53, я просто перепутал тесты.  А53 оказался на 15 % производительней тут, что, конечно, можно списать на что угодно, разная память, разный кеш, фазы Луны и тп.

Share this post


Link to post
Share on other sites

На H7 и везде unroll разрешен.

Quote

C:\user>arm-none-eabi-gcc --version                                                                                                                 arm-none-eabi-gcc.EXE (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


 

 

Edited by GenaSPB

Share this post


Link to post
Share on other sites

В некоторых местах - обсчет FIR фильтров в программе - давало прирост. Если не использует, значит есть соображения.
Как обычно, замечено что на организации циклов можно сэкономить.
Но я проверял и "оптимизированный" вариант - не лучше. Иногда хуже.

 

Edited by GenaSPB

Share this post


Link to post
Share on other sites

мда, а Ryzen в виртуалке в 14 раз уделал А53, с поправкой на частоту в 6 раз.  Вроде такая древняя вещь с кучей костылей для исполнения старого кода, а летает, что АРМу и не снилось.. 

Share this post


Link to post
Share on other sites

static void RAMFUNC_NONILINE cplxmlafast(cplxf *s, cplxf *d, cplxf *ref, int len) {
	int i;
	for (i = 0; i < len; ++ i) {
		d [i].r += s [i].r * ref [i].r - s [i].i * ref [i].i;
		d [i].i += s [i].i * ref [i].r + s [i].r * ref [i].i;
	}
}

 

Share this post


Link to post
Share on other sites

Немного оптимизировал структуру данных. Итог - при той же функциональности 2кГц без разворачивания цикла и 2.09кГц при разворачивании "на 4". Это при работе из DDR с включенной когерентностью кэшей для двух ядер.

Edited by Шаманъ

Share this post


Link to post
Share on other sites
1 minute ago, Шаманъ said:

Немного оптимизировал структуру данных. Итог - при той же функциональности 2кГц без разворачивания цикла и 2.09кГц при разворачивании "на 4". Это при работе из DDR с включенной когерентностью кэшей для двух ядер.

как оптимизировали? Ей выравнивание да, может помочь.

Share this post


Link to post
Share on other sites

Нет выравнивание не при чем. Задумайтесь как то, что Вы передает функции загружать в регистры VFP и сразу станет ясно, что это делать придется через одно место. На С оно красиво, а в коде увы...

Share this post


Link to post
Share on other sites
12 minutes ago, Шаманъ said:

Нет выравнивание не при чем. Задумайтесь как то, что Вы передает функции загружать в регистры VFP и сразу станет ясно, что это делать придется через одно место. На С оно красиво, а в коде увы...

я вас не совсем понял, вернее не понял совсем, но от allign (32) поимел чуть ли не двукратный прирост. Можно перепроверить, вдруг ошибка была

Да и что тут можно руками улучшить тоже не знаю

 

876907947_.thumb.png.543016de889d5ecbdbbbc0f6263eedf5.png

гм, что-то не неоновый код. Выравнивание помогало только на НЕОНе

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Cihejdic.html

Share this post


Link to post
Share on other sites

Ручная оптимизация с intrinsic-функциями дала 2.2кГц. Наверное можно еще попереставлять команды для лучшей загрузки конвеера, но уже лениво...

Таки А9 в разы быстрее М7, но подход нужен аккуратный.

Share this post


Link to post
Share on other sites
3 minutes ago, Шаманъ said:

Ручная оптимизация с intrinsic-функциями дала 2.2кГц. Наверное можно еще попереставлять команды для лучшей загрузки конвеера, но уже лениво...

Таки А9 в разы быстрее М7, но подход нужен аккуратный.

код дадите? (у меня это вполне используемый код, буду премного благодарен).

Share this post


Link to post
Share on other sites
22 minutes ago, DASM said:

код дадите?

Даю, правда использовать вряд ли у Вас получится - я ведь писал, ключевой момент более удобная структура обрабатываемых данных. Кроме того порядок комманд может оказаться не оптимальным для А53 (впрочем я не утверждаю, что он оптимален для А9 :)). И да, если исходные массивы положить в SRAM, то 2.5кГц выходит.

void cplxmla(const float * sr,
            const float * si,
            const float * refr,
            const float * refi,
            float * restrict dr, 
            float * restrict di, 
            int len) 
{ 
   len = len / 4;
   while(len--)
   {
      float32x4_t sr_v = vld1q_f32(sr);
      float32x4_t si_v = vld1q_f32(si);
      float32x4_t refr_v = vld1q_f32(refr);
      float32x4_t refi_v = vld1q_f32(refi);     
      float32x4_t ar_v = vmulq_f32(sr_v, refr_v);
      float32x4_t dr_v = vld1q_f32(dr);
      float32x4_t ai_v = vmulq_f32(si_v, refr_v);
      float32x4_t di_v = vld1q_f32(di);
      ar_v = vmlsq_f32(ar_v, si_v, refi_v);
      ai_v = vmlsq_f32(ai_v, sr_v, refi_v);
      dr_v = vaddq_f32(dr_v, ar_v);
      di_v = vaddq_f32(di_v, ai_v);
      sr += 4; 
      si += 4; 
      refr += 4;
      refi += 4;
      vst1q_f32(dr, dr_v);
      dr += 4; 
      vst1q_f32(di, di_v);
      di += 4; 
	}
}

 

Share this post


Link to post
Share on other sites

Так проект , который таки решился довести до ума - он на А8. А15 и А53 - потом играться. Спасибо, буду гонять, может еще что накопаю. Тут , правда тонкость с данными - я использую комплексную свертку, в которые re - im это на самом деле вещественные отсчеты левого и правого каналов стерео. И они как бы ложатся в память изначально в моем порядке. Даст ли их перетасовка для вашего кода выигрыш в итоге или нет - надо прикинуть будет. Я тест упростил,  у меня длинная свертка по  overlap save, коэффициенты из *si не на месте стоят, но сути дела не меняет это.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.