Михась 2 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Библиотека DSP STM32F4xx_DSP_StdPeriph_Lib_V1.4.0 Файл arm_add_q31.c Прошу разъяснить, какие отличия архитектуры Cortex-M3, M4 заставляют группировать по 4 операции в цикле, в отличии от одной операции в цикле для M0. Это для правильной работы конвеера? /** * @brief Q31 vector addition. * @param[in] *pSrcA points to the first input vector * @param[in] *pSrcB points to the second input vector * @param[out] *pDst points to the output vector * @param[in] blockSize number of samples in each vector * @return none. * * <b>Scaling and Overflow Behavior:</b> * \par * The function uses saturating arithmetic. * Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated. */ void arm_add_q31( q31_t * pSrcA, q31_t * pSrcB, q31_t * pDst, uint32_t blockSize) { uint32_t blkCnt; /* loop counter */ #ifndef ARM_MATH_CM0_FAMILY /* Run the below code for Cortex-M4 and Cortex-M3 */ q31_t inA1, inA2, inA3, inA4; q31_t inB1, inB2, inB3, inB4; /*loop Unrolling */ blkCnt = blockSize >> 2u; /* First part of the processing with loop unrolling. Compute 4 outputs at a time. ** a second loop below computes the remaining 1 to 3 samples. */ while(blkCnt > 0u) { /* C = A + B */ /* Add and then store the results in the destination buffer. */ inA1 = *pSrcA++; inA2 = *pSrcA++; inB1 = *pSrcB++; inB2 = *pSrcB++; inA3 = *pSrcA++; inA4 = *pSrcA++; inB3 = *pSrcB++; inB4 = *pSrcB++; *pDst++ = __QADD(inA1, inB1); *pDst++ = __QADD(inA2, inB2); *pDst++ = __QADD(inA3, inB3); *pDst++ = __QADD(inA4, inB4); /* Decrement the loop counter */ blkCnt--; } /* If the blockSize is not a multiple of 4, compute any remaining output samples here. ** No loop unrolling is used. */ blkCnt = blockSize % 0x4u; while(blkCnt > 0u) { /* C = A + B */ /* Add and then store the results in the destination buffer. */ *pDst++ = __QADD(*pSrcA++, *pSrcB++); /* Decrement the loop counter */ blkCnt--; } #else /* Run the below code for Cortex-M0 */ /* Initialize blkCnt with number of samples */ blkCnt = blockSize; while(blkCnt > 0u) { /* C = A + B */ /* Add and then store the results in the destination buffer. */ *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ + *pSrcB++); /* Decrement the loop counter */ blkCnt--; } #endif /* #ifndef ARM_MATH_CM0_FAMILY */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба пардон за оффтоп, но это уже кошмар какой-то while(blkCnt > 0u) { // тело цикла blkCnt--; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arhiv6 14 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Почему такая конструкция считается кошмаром? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Почему такая конструкция считается кошмаром? Потому что это for(;;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Почему такая конструкция считается кошмаром? В основном потому, что для С-стиля совершенно естественно написать while( blkCnt-- ) это одно из так называемых "идеоматических выражений" в языке, устойчивая, часто встречающаяся конструкция, которую все знают с первых дней изучения языка и с пониманием которой не возникает никаких проблем как раз ввиду частого использования. Т.е. появление в коде такой конструкции с головой выдаёт недостаток опыта работы на С/С++ и то, что человек мало читал хорошего чужого кода. Это как стилистические несуразности в прозе - сразу видно что автор ни Толстого с Пушкиным, ни даже "Трёх мушкетёров" почти не читал, букварём ограничился. Впрочем там и аналогов грамматических ошибок хватает, я в кубе уже не меньше десятка нашёл. А уж уточнение что ноль беззнаковый (0u)- это просто шедевр. Первый операнд в операции сравнения, blkCnt, объявлен как uint32_t и потому второй операнд всё равно будет приведён к unsigned типу и сравнение будет беззнаковым. Не говоря уж о том, что разница между знаковым и беззнаковым сравнением будет только когда этот несчастный blkCnt перевалит границу в 2 Гига, что на STM32 означает никогда, у него столько памяти просто нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ukpyr 0 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба появление в коде такой конструкции с головой выдаёт недостаток опыта работы на С/С++а может и наоборот - обнаружили что компилер лучше оптимизирует именно этот вариант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба while( blkCnt-- ) Это будет другая конструкция, с преддекрементом индексной переменной относительно тела цикла а может и наоборот - обнаружили что компилер лучше оптимизирует именно этот вариант. Это было бы странно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 18 ноября, 2015 Опубликовано 18 ноября, 2015 (изменено) · Жалоба Это будет другая конструкция, с преддекрементом индексной переменной относительно тела цикла Эта переменная ни разу не используется в теле цикла, кроме, собственно, сравнения в while() и постдекремента. Изменено 18 ноября, 2015 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Это будет другая конструкция, с преддекрементом индексной переменной относительно тела цикла Разве это не постдекремент? Сначала проверили blkCnt, приняли решение идти в цикл, а потом декрементировали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Разве это не постдекремент? Сначала проверили blkCnt, приняли решение идти в цикл, а потом декрементировали. относительно тела цикла но в данном случае без разницы, как уже выяснили. а я бы все равно for() написал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 7 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба А уж уточнение что ноль беззнаковый (0u)- это просто шедевр. Так делают, чтобы компилер не сыпал варнинги, типа "сравнение беззнакового и знакового". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба но в данном случае без разницы, как уже выяснили. а я бы все равно for() написал. Как же, for()? Здесь не бесконечный цикл. Все работает, пока до нуля не усохнет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба Прошу разъяснить, какие отличия архитектуры Cortex-M3, M4 заставляют группировать по 4 операции в цикле, в отличии от одной операции в цикле для M0. Это для правильной работы конвеера? в вашем коде идет считывание и сохранение. Это инструкции LDM и STM для M3 аргументами могуть быть все регистры, но из-за особенностей реализации компиляторов C, используются только четыре вот к примеру как идет копирование в СМ3 - сразу по 16 байт ( четыре регистра ) LDM R1!, {R3-R5, R12} SUBS R2, R2, #16 STM R0!, {R3-R5, R12} BCS.N 0x295a но в CM0 для инструкций LDM и SDM есть ограничение reglist and Rn are limited to R0-R7. P.S. словоблуды до While докопались Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 18 ноября, 2015 Опубликовано 18 ноября, 2015 · Жалоба для M3 аргументами могуть быть все регистры, но из-за особенностей реализации компиляторов C, используются только четыре Но тут почему-то 8 регистров за раз! Это не считая счётчика цикла и указателей src/dst. Какой компилятор такое умеет, интересно? P.S. словоблуды до While докопались Вот да. А оригинальный-то вопрос интересный! Следующий холивар "только последние дилетанты используют пробелы для отступов в коде!!!" :-( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Михась 2 19 ноября, 2015 Опубликовано 19 ноября, 2015 · Жалоба Пробовал компилировать для разных архитектур, ничего принципиально выигрышного от такой записи не увидел (но я программист - никакой). Может это наследие от типов q7 и q15 для использования simd инструкций? Но у М3 нет simd. Так ничего и не понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться