Перейти к содержанию
    

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 дала обратный эффект, причем очень сильный.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 % производительней тут, что, конечно, можно списать на что угодно, разная память, разный кеш, фазы Луны и тп.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На 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.


 

 

Изменено пользователем GenaSPB

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Изменено пользователем GenaSPB

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты


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;
	}
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Изменено пользователем Шаманъ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Шаманъ said:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Шаманъ said:

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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; 
	}
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...