zltigo 2 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Только в таблице у него 8 байтов Это дело даже не второе, а третье, ибо байты кода это еще команды которые еще исполняются, а некоторые, типа PUSH/POP нескольких регистров, еще и не за один такт. Как сделать в Keil то же, что и в IAR? Написать на ASM :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Это дело даже не второе, а третье, ибо байты кода это еще команды которые еще исполняются, а некоторые, типа PUSH/POP нескольких регистров, еще и не за один такт. Давайте проверим. Число -2147483647 (т.е. -(2^31 - 1), максимально допустимое для функции) Keil преобразовал за 207 тактов (сравнивал счетчик тактов перед вызовом itoad и после нее). Сколько у IAR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Давайте проверим. :) Думаете дополнительные команды ускорят процесс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба :) Думаете дополнительные команды ускорят процесс? Хочу знать, насколько замедлят. MOV r2,#0x20202020 выполняется за 1 такт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Хочу знать, насколько замедлят. Посчитайте на пальцах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Посчитайте на пальцах. На пальцах до 200? У меня столько пальцев нет :) Я лучше на бумаге :) и калькуляторе. А SDIV r0,r0,r3 выполняется за 11 тактов... upd. Не всегда! - обнаружил и 10 тактов, и 9 тактов, похоже, от чисел зависит. О! чем меньше делимое, тем меньше тактов. Видел 4 такта. ... а MLS r2,r3,r0,r2 всего за 2. Так что на пальцах, извините, никак не посчитать. Максимальное количество тактов для SDIV заметил 12. Где про такты написано? 2 zltigo Ну если упорно не хотите нормальное сравнение сделать... :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба 2 zltigo Ну если упорно не хотите нормальное сравнение сделать... :) Меня интересует результат компиляции - уже четко видна и разница и порядок отличия. А заниматься попугаемерами в симуляторах и иже с ним не собираюсь. Тем более, что железо с его ограничениями отдельная песня. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба А SDIV r0,r0,r3 выполняется за 11 тактов... upd. Не всегда! - обнаружил и 10 тактов, и 9 тактов, похоже, от чисел зависит. О! чем меньше делимое, тем меньше тактов. Видел 4 такта. ... Максимальное количество тактов для SDIV заметил 12. Где про такты написано? Cortex-M3 Technical Reference Manual Divide: 2-12 Cycles DIV timings depend on dividend and divisor. DIV is interruptible (abandoned/restarted), with worst case latency of one cycle. When dividend and divisor are similar in size, divide terminates quickly. Minimum time is for cases of divisor larger than dividend and divisor of zero. A divisor of zero returns zero (not a fault), although a debug trap is available to catch this case. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 июля, 2010 Опубликовано 2 июля, 2010 · Жалоба Перепробовал все "извращения" со сравнениями и др. в надежде уменьшить количество байтов. Кто бы мне объяснил, почему в некоторых местах команда MOV r2,... кодируется двумя байтами, а в некоторых четырьмя? И не только эта команда. ;;;63 uint8_t sign = '+'; 000010 222b MOVS r2,#0x2b ;;;64 if (!number) return; 000012 2800 CMP r0,#0 000014 d010 BEQ |L1.56| ;;;65 if (number < 0) { 000016 da03 BGE |L1.32| ;;;66 number = -number; 000018 f1c00000 RSB r0,r0,#0 ;;;67 sign = '-'; 00001c f04f022d MOV r2,#0x2d |L1.32| ;;;68 } Как-то связано с операторами перехода по результатам сравнения. Как будто учитывается конвейер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 июля, 2010 Опубликовано 2 июля, 2010 · Жалоба Думаю, хуже не станет, если я доложу, что уменьшил количество тактов для преобразования -2147483647 в строку до 195. Жаль, что не байтов. void itoad(int32_t number, uint8_t *string) { *(uint32_t *)(string) = 0x20202020; *(uint32_t *)(string + 4) = 0x20202020; *(uint32_t *)(string + 8) = 0x00302020; string += 10; uint8_t sign = '+'; if (!number) return; if (number < 0) { number = -number; sign = '-'; } do { *string-- = number % 10 + '0'; } while (number /= 10); *string = sign; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 3 июля, 2010 Опубликовано 3 июля, 2010 · Жалоба Давайте может функцию настройки PLL по-оптимизируем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 3 июля, 2010 Опубликовано 3 июля, 2010 · Жалоба Давайте может функцию настройки PLL по-оптимизируем? Я пользуюсь библиотечной. Надеюсь, ее писали мастера. Да и используется функция однократно. Принципы, как нужно писать, здесь уже оговорены. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 10 июля, 2010 Опубликовано 10 июля, 2010 (изменено) · Жалоба Думаю, хуже не станет, если я доложу, что уменьшил количество тактов для преобразования -2147483647 в строку до 195. Жаль, что не байтов. Я думаю, вашу функцию можно еще чуть чуть уменьшить. void itoad(int32_t number, uint8_t *string) { *(uint32_t *)(string) = 0x20202020; *(uint32_t *)(string + 4) = 0x20202020; *(uint32_t *)(string + 8) = 0x00302020; if (!number) return; if (number < 0) { number = -number; *string = '-'; } else *string = '+'; string += 11; do { *--string = number % 10 + '0'; } while (number /= 10); } Или нет? Изменено 10 июля, 2010 пользователем rezident Излишнее цитирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Wano 0 10 июля, 2010 Опубликовано 10 июля, 2010 · Жалоба Хорошо если по правому боку ровнять: string += 10; или =11 или =бесконечность А если нет, что с пр́обелами? Двигать надо будет. Лучше бы сразу на миллиард, потом на сотню лимонов... А *(uint32_t *)(string) = 0x20202020; работает в любом случае? Всегда начало char массива 4-aligned (если умышленно не двигать указатель)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 11 июля, 2010 Опубликовано 11 июля, 2010 · Жалоба А *(uint32_t *)(string) = 0x20202020; работает в любом случае? Всегда начало char массива 4-aligned (если умышленно не двигать указатель)? Написано под Кортекс, ему по барабану выравнивание, разве что незначительно вырастет время выполнения инструкции. Правда, это относится только к инструкциям, работающим с единичными словами - LDR, LDRH, STR, STRH. Мультивордовые LDRD/STRD/LDM/STM и т.д. в случае невыравненного на границу 4 байт доступа всё равно приведут к исключению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться