Alex-lab 6 4 октября, 2023 Опубликовано 4 октября, 2023 · Жалоба 1 hour ago, jcxz said: Они что - volatile Да, некоторые были volatile, убрал полностью, общее время сократилось с 2,6 до 2,15. 1 hour ago, Quasar said: А PLL ядра-то правильно настроена? Да, таймер работает корректно. 25 minutes ago, firstvald said: а сишника не будет я так понял Первый пост чем не устраивает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 23 4 октября, 2023 Опубликовано 4 октября, 2023 · Жалоба опс а он скрыт был. нужно разворачивать. не увидел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex-lab 6 4 октября, 2023 Опубликовано 4 октября, 2023 · Жалоба В целом не особо разобравшись в причинах, убрал все volatile и сделал предзагрузку данных из массивов в переменные, и в целом уложился в требуемый интервал с 11 до 8.5 мкс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 57 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 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; } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 162 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 30 минут назад, dimka76 сказал: Если в вашей функции все данные поместить в структуру и часть данные представить массивами, то размер вашей функции можно сократить на 136 байт... Откуда предположение, что u8_p может принимать только 1 и 2? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 57 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба On 10/5/2023 at 10:08 AM, Arlleex said: Откуда предположение, что u8_p может принимать только 1 и 2? Чуйка ))) Если не так, то пусть ТС меня поправит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 162 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба Тут еще пару тактов: 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). 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 57 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба On 10/5/2023 at 10:25 AM, Arlleex said: Тут еще пару тактов: Вообще, у меня существенный выигрыш получился только за счет того, что поместил все данные в структуру. On 10/5/2023 at 10:25 AM, Arlleex said: Тут еще пару тактов: Мой компилятор наоборот дал прирост кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 162 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 12 минут назад, dimka76 сказал: Мой компилятор наоборот дал прирост кода. Лучше, все-таки, считать такты. А, хотя да, на Cortex не факт что быстрее будет. У меня компилятор, кстати, автоматом конвертнул в вариант, очень похожий на мой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dOb 10 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 20 часов назад, Alex-lab сказал: оставив лишь один switch вместо ifs? Как я поступаю в таких случаях: Все флаги загоняю в одну переменную. типа Bit0, Bit1 и так далее. Эти флаги выставляю или снимаю макросом через BitBand регион. Типа: BIT_RAM(StXYZ.mStatus,bpXX) =1; А потом switch case где расписаны все возможные варианты. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex-lab 6 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 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 мкс нс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 223 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 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). Боюсь, что ваш вариант может оказаться медленнее, чем исходный. Так как - ветвление идёт вперёд и размер блока по "ДА" - небольшой, то значит компилятор вполне вправе для проверки на ==0 применить 3 команды CBNZ подряд. А в вашем случае он должен как минимум: ORRS, ORRS, EORS, BNE - 4 команды. Но это всё - экономия на спичках. Если уж хочется оптимизировать, то без включения головы и перетряхивания всего алгоритма - никак. Если предположить, что все флаговые переменные (коих в исходнике ТСа вроде == 5 шт.) можно поместить в одну переменную, которую считать в начале функции, а потом только проверять отдельные её поля, то не будет множества чтений из ОЗУ, эта переменная будет считана в регистр в начале функции один раз. И потом только анализироваться. Простыми операциями сдвига. Вот тогда и будет реальное ускорение. Может даже кратное. Так как освободится много регистров для полезных операций и не будет кучи лишних чтений памяти. Сейчас же функция ТС задушена обилием переменных и оптимизатор не может её улучшить без помощи программиста. Объединить скорее всего можно, так как в пределах функции эти переменные только читаются. И скорее всего - за пределами функции модифицируются редко. И скорее всего модифицироваться должны сразу все, атомарно. Хотя это всё конечно предположения и ТСу виднее. А все эти замены проверок - экономия на спичках. Не более. 1 час назад, Alex-lab сказал: Да, так и с делал. Чуток помогло выиграть, порядка 150 мкс. Т.е. - даже в минус ушли???! Вы же писали, про 2.6мкс. Получается 2.6-150 = -147.4 мкс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex-lab 6 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 2 hours ago, Arlleex said: Тут еще пару тактов: if (!adc_d.b_diag_flag && !adc_d.b_inject && !adc_d.b_DontVoltage) Да, этот блок я заменил на одну переменную, предварительно собирающую все эти значения в кучу в начале, т.к. используются они два раза. 7 minutes ago, jcxz said: Если уж хочется оптимизировать, то без включения головы и перетряхивания всего алгоритма - никак. Мой изначальный вопрос был вообще не об оптимизации, а почему такие простые операции превращаются в такой долго исполнимый код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 223 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба 1 минуту назад, Alex-lab сказал: Мой изначальный вопрос был вообще не об оптимизации, а почему такие простые операции превращаются в такой долго исполнимый код. На вашем месте я бы в первую очередь задумался: Почему мой компилятор при компиляции этой функции совсем не использует регистры >R4 ? На 5 регистрах (R0-R4) нормально сложный код не построишь. И отсюда и тормоза вашего кода. Советую внимательно проанализировать опции компилятора - где-то в них что-то не то прописано. Имхо. Ну или как уже советовал выше - заменить компилятор. PS: Не должен нормальный компилятор для Cortex-M4 не знать о существовании R5-R12,LR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 57 5 октября, 2023 Опубликовано 5 октября, 2023 · Жалоба On 10/5/2023 at 12:43 PM, Alex-lab said: Мой изначальный вопрос был вообще не об оптимизации, а почему такие простые операции превращаются в такой долго исполнимый код. Кстати, вот тут вы сравниваете переменные разного типа и разного размера if (u16_Umaxn < i32_ADCcor[1]) Вы абсолютно уверены в работоспособности такой конструкции ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться