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

STM32F334 медленное исполнение?

1 hour ago, jcxz said:

Они что - volatile

Да, некоторые были volatile, убрал полностью, общее время сократилось с 2,6 до 2,15.

1 hour ago, Quasar said:

А PLL ядра-то правильно настроена?

Да, таймер работает корректно.

25 minutes ago, firstvald said:

а сишника не будет я так понял

Первый пост чем не устраивает?

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


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

В целом не особо разобравшись в причинах, убрал все volatile и сделал предзагрузку данных из массивов в переменные, и в целом уложился в требуемый интервал с 11 до 8.5 мкс.

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


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

On 10/5/2023 at 1:53 AM, Alex-lab said:

В целом не особо разобравшись в причинах, убрал все volatile и сделал предзагрузку данных из массивов в переменные, и в целом уложился в требуемый интервал с 11 до 8.5 мкс.

Если в вашей функции все данные поместить в структуру и часть данные представить массивами, то размер вашей функции можно сократить на 136 байт. А следовательно,

и время выполнения еще сократится.

А если сравнивать листинг, получившийся у меня, с вашим листингом, то мой размер вообще в два раза меньше, чем у вас.

У меня тоже компилятор GCC, оптимизация Os

 

struct{
     uint32_t b_voltamp, b_inject, b_diag_flag, b_DontVoltage, u32_countipnp, u32_countipn, u32_countQinj;
     uint8_t u8_p;
     uint64_t u64_tempQinj;
     int32_t i32_ADCcor[10];
     uint64_t u64_tempinp2[2], u64_tempinp[2];
     uint32_t u32_countinp[2];
     uint16_t u16_Umaxpn[2];//Number of negative currents
} adc_d;

void countiu (void) {
	uint32_t idx = adc_d.u8_p-1;

	if(adc_d.b_voltamp == 1)	{
		adc_d.u64_tempinp[idx] += adc_d.i32_ADCcor[0];
		++adc_d.u64_tempinp[idx];
		++adc_d.u32_countipn;
	}else if(adc_d.b_voltamp == 0)	{
		adc_d.u64_tempinp2[idx] += adc_d.i32_ADCcor[0];
	}

  ++adc_d.u32_countipnp;                          //Number of total times for averaging chronogram data

  if (adc_d.b_inject) {                           //Calculation of injected charge separately
	  adc_d.u64_tempQinj += adc_d.i32_ADCcor[0];
    ++adc_d.u32_countQinj;
  }

  if (!adc_d.b_diag_flag && !adc_d.b_inject && !adc_d.b_DontVoltage) {          //Exclude amplitude of diagnostic and injecting pulses from peaks calculation
    if(adc_d.u16_Umaxpn[idx] < adc_d.i32_ADCcor[1]) {
    	adc_d.u16_Umaxpn[idx]  = (3 * adc_d.u16_Umaxpn[idx] + adc_d.i32_ADCcor[1]) >> 2;
    }
  }
}

 

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


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

30 минут назад, dimka76 сказал:

Если в вашей функции все данные поместить в структуру и часть данные представить массивами, то размер вашей функции можно сократить на 136 байт...

Откуда предположение, что u8_p может принимать только 1 и 2?

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


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

On 10/5/2023 at 10:08 AM, Arlleex said:

Откуда предположение, что u8_p может принимать только 1 и 2?

Чуйка )))
Если не так, то пусть ТС меня поправит.

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


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

Тут еще пару тактов:

if (!adc_d.b_diag_flag && !adc_d.b_inject && !adc_d.b_DontVoltage)

==

if ((adc_d.b_diag_flag | adc_d.b_inject | adc_d.b_DontVoltage) ^ 1)

если все переменные 0/1 (bool).

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


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

On 10/5/2023 at 10:25 AM, Arlleex said:

Тут еще пару тактов:

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

On 10/5/2023 at 10:25 AM, Arlleex said:

Тут еще пару тактов:

Мой компилятор наоборот дал прирост кода.

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


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

12 минут назад, dimka76 сказал:

Мой компилятор наоборот дал прирост кода.

Лучше, все-таки, считать такты.

А, хотя да, на Cortex не факт что быстрее будет.

У меня компилятор, кстати, автоматом конвертнул в вариант, очень похожий на мой.

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


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

20 часов назад, Alex-lab сказал:

оставив лишь один switch вместо ifs?

Как я поступаю в таких случаях: Все флаги загоняю в одну переменную. типа Bit0,  Bit1  и так далее.

Эти флаги выставляю или снимаю  макросом через  BitBand регион.    Типа:   BIT_RAM(StXYZ.mStatus,bpXX) =1;

А потом switch  case где расписаны все возможные варианты.

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


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

3 hours ago, dimka76 said:

представить массивами, то размер вашей функции можно сократить на 136 байт. А следовательно,

и время выполнения еще сократится.

Сокращать размер нет нужды. Но подход интересный. По факту, обращение к массивам сильно снижает быстродействие.

2 hours ago, Arlleex said:

u8_p может принимать только 1 и 2?

Еще 0 и 3, но для них ничего делать не надо.

1 hour ago, dOb said:

Все флаги загоняю в одну переменную. типа Bit0,  Bit1  и так далее.

Да, так и с делал. Чуток помогло выиграть, порядка 150 мкс нс.

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


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

2 часа назад, Arlleex сказал:

Тут еще пару тактов:

if (!adc_d.b_diag_flag && !adc_d.b_inject && !adc_d.b_DontVoltage)

==

if ((adc_d.b_diag_flag | adc_d.b_inject | adc_d.b_DontVoltage) ^ 1)

если все переменные 0/1 (bool).

Боюсь, что ваш вариант может оказаться медленнее, чем исходный. :wink: Так как - ветвление идёт вперёд и размер блока по "ДА" - небольшой, то значит компилятор вполне вправе для проверки на ==0 применить 3 команды CBNZ подряд. А в вашем случае он должен как минимум: ORRS, ORRS, EORS, BNE - 4 команды.

 

Но это всё - экономия на спичках. Если уж хочется оптимизировать, то без включения головы и перетряхивания всего алгоритма - никак.

Если предположить, что все флаговые переменные (коих в исходнике ТСа вроде == 5 шт.) можно поместить в одну переменную, которую считать в начале функции, а потом только проверять отдельные её поля, то не будет множества чтений из ОЗУ, эта переменная будет считана в регистр в начале функции один раз. И потом только анализироваться. Простыми операциями сдвига. Вот тогда и будет реальное ускорение. Может даже кратное. Так как освободится много регистров для полезных операций и не будет кучи лишних чтений памяти. Сейчас же функция ТС задушена обилием переменных и оптимизатор не может её улучшить без помощи программиста.

Объединить скорее всего можно, так как в пределах функции эти переменные только читаются. И скорее всего - за пределами функции модифицируются редко. И скорее всего модифицироваться должны сразу все, атомарно. Хотя это всё конечно предположения и ТСу виднее.

А все эти замены проверок - экономия на спичках. Не более.  :wink:

1 час назад, Alex-lab сказал:

Да, так и с делал. Чуток помогло выиграть, порядка 150 мкс.

Т.е. - даже в минус ушли???! :shok: Вы же писали, про 2.6мкс. Получается 2.6-150 = -147.4 мкс.

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


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

2 hours ago, Arlleex said:

Тут еще пару тактов:

if (!adc_d.b_diag_flag && !adc_d.b_inject && !adc_d.b_DontVoltage)

Да, этот блок я заменил на одну переменную, предварительно собирающую все эти значения в кучу в начале, т.к. используются они два раза.

7 minutes ago, jcxz said:

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

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

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


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

1 минуту назад, Alex-lab сказал:

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

На вашем месте я бы в первую очередь задумался: Почему мой компилятор при компиляции этой функции совсем не использует регистры >R4 ?

На 5 регистрах (R0-R4) нормально сложный код не построишь. И отсюда и тормоза вашего кода. Советую внимательно проанализировать опции компилятора - где-то в них что-то не то прописано. Имхо. Ну или как уже советовал выше - заменить компилятор.

PS: Не должен нормальный компилятор для Cortex-M4 не знать о существовании R5-R12,LR.

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


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

On 10/5/2023 at 12:43 PM, Alex-lab said:

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

Кстати, вот тут вы сравниваете переменные разного типа и разного размера

if (u16_Umaxn < i32_ADCcor[1])

Вы абсолютно уверены в работоспособности такой конструкции ?

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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