ViKo 1 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба Следуя рекомендациям, слегка модернизировал код. void itoa(int16_t Number, uint8_t *String) { uint8_t Sign = ' '; if (Number > 0) Sign = '+'; if (Number < 0) { Sign = '-'; Number = - Number; } String[6] = '\0'; int8_t i = 5; div_t QR = {Number, 0}; do { QR = div(QR.quot, 10); String[i--] = QR.rem + '0'; } while (QR.quot); String[i] = Sign; for (i--; i >= 0; i--) String[i] = ' '; } Результат оказался несколько неожиданным :) Ни в первом, ни во втором случае RealView MDK-ARM 4.10 не использует команды деления вообще. А код оказался равным по размеру (и по содержанию, похоже). Так что можно сделать вывод, что / и % компилятор все-же объединил. А заняла функция деления примерно 80 команд (не машинных тактов, а именно строк в ассемблерном коде). 2 Непомнящий Евгений На таком принципе основан мой код для PIC, который чуть выше в файле лежит. Только написан на ассемблере. Посему повторяю рекомендации откомпилировать и посмотреть на результат с / % для всех ранее помянутых ядер. Так-же напомню, что слово "гуано" относилось далеко не только к использованию / %. Для всех ядер - это вы уж слишком многого от меня хотите. :) У меня и компиляторов таких нет. А для Cortex-M3 я написал и откомпилировал, и из ваших высказываний так и не понял, что бы такого можно было улучшить в моем коде. А примера, как надо делать, вы не привели. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvSerge 0 26 июня, 2010 Опубликовано 26 июня, 2010 (изменено) · Жалоба Следуя рекомендациям, слегка модернизировал код. вы бы озвучили с какой целью модифицировался код. надо "быстрый алгоритм", "короткий код", "читаемый текст" или еще что-то? Нужен быстрый и не требовательный алгоритм - в atoi_v1. слишком длинное решение - посмотрите в atoi_v2. Операции деления отсутствуют как класс. P.S. тексты в файлах - написаны за 2 минуты и на работоспособность не проверялись. демонстрируется метод табличного решения задачи. ничего более. P.P.S. метод имеет смысл применять на простых контроллерах без аппаратного умножителя. (с умножителем надо думать). Сергей. itoa_v1.txt ito1_v2.txt Изменено 26 июня, 2010 пользователем ssvSerge Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба 2 ssvSerge В ваших алгоритмах число записывается задом наперед, надо iStorePos++; и нет индикации знака числа. А в остальном - можно и так. Для чего код модернизировал - сделать то, что имею, лучше, оптимальнее. В идеале - оптимальнее и по производительности, и по компактности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvSerge 0 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба В алгоритмах число записывается задом наперед и нет индикации знака числа. кроме этого нет проверки на 0 и в одном из разрядов нет проверки на "bIsDigitPresent". Это если уж быть точным. Но это мелочи - код и не претендовал на работоспособность. Главное, что подход понятен. код сделать лучше, оптимальнее. Слово "оптимальнее" следует исключить из лексикона как антинаучное. Есть критерии: скорость, объем, читабельность и т.д. Для каждого человека, проекта, процессора критерии изменяются. В идеале - оптимальнее и по производительности, и по компактности. ну так озвучьте цифры какой из вариантов (табличный или с делениями) оптимальнее в конкретно вашем случае. на ваших процессорах и в ваших глазах. Сергей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба ну так озвучьте цифры какой из вариантов (табличный или с делениями) оптимальнее в конкретно вашем случае. на ваших процессорах и в ваших глазах. В данный момент меня занимает алгоритм от aaarrr, поискал по компу своему книжку по цифровые трюки, но не нашел. А ведь была. Нельзя ли его расширить, чтобы принимал все числа. Второй вариант - преобразовать bin в BCD, а затем уже превратить в строку. Табличный способ меня не привлекает из-за громоздкости. Точные цифры по быстродействию и размеру кода я не смотрел. Если будет что сказать, доложу. P.S. Определился, пожалуй, что для меня значит оптимальность. = Компактность кода. А быстродействие мне STM32 и так обеспечит. P.P.S. Причем, часто бывает, что компактный код и работает быстро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба Для всех ядер - это вы уж слишком многого от меня хотите. :) У меня и компиляторов таких нет. Тем не менее, Вы уже второй раз утверждаете, что писали с оглядкой на Cortex? Лично я воспринял это, как то, что Вы знаете, что творите. из ваших высказываний так и не понял, что бы такого можно было улучшить в моем коде. Хорошо,не затрагивая, так сказать основ, только то, что сразу режет глаз. void si16toad (int16_t Number, char * StrBuf) { char Sign = ' '; // Зачем-то завели малополезную переменную 'Sign' if (Number > 0) Sign = '+'; if (Number < 0) { Sign = '-'; Number = -Number; } StrBuf[6] = '\0'; signed char i = 5; // Cortex говорите? Тогда за не 32 bit переменные, где в этом нет // небходимости по рукам надо давать. Да и сама переменная лишняя - только команд push/pop добавляет // А за использование "массивов" вместо указателей - еще один раз do { StrBuf[i--] = Number % 10 + '0'; Number /= 10; // 32 bit контроллер? Тогда зачем его беднягу опять без всякой надобности // заставлять с 16bit 'Number' работать? Сразу несколько лишних команд в цикле } while (Number); StrBuf[i] = Sign; // Цикл заполнения пробелами не более, чем 4x ,байтиков. А как это на 32битниках, тем более на // Cortex это можно сделать одной командой?( ну ладно двумя - одна регистр пробелами заполняет) for (i--; i >= 0; i--) StrBuf[i] = ' '; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvSerge 0 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба для меня оптимальность = Компактность кода. бывает, что компактный код и работает быстро.о - вот теперь всё понятно. табличные методы в таких условиях, конечно, проигрывают. я хотел сказатать только, что таблицу можно сделать на базе "2 в степени" и заниматься BCD сложением. Значительно компактнее, чем десятичная таблица, и реализация на ASM проста до смешного. Хотя в скорости, конечно, уступает десятичной. Сергей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба В данный момент меня занимает алгоритм от aaarrr, поискал по компу своему книжку по цифровые трюки, но не нашел. А ведь была. Нельзя ли его расширить, чтобы принимал все числа. Да нет там никаких трюков, кроме обычной арифметики :) Первым умножением число переводится в представление 4.28, дальше все понятно. Расширить в каком направлении? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба // Зачем-то завели малополезную переменную 'Sign' // Cortex говорите? Тогда за не 32 bit переменные, где в этом нет // небходимости по рукам надо давать. Да и сама переменная лишняя - только команд ush/pop добавляет // А за использование "массивов" вместо указателей - еще один раз // 32 bit контроллер? Тогда зачем его беднягу опять без всякой надобности // заставлять с 16bit 'Number' работать? Сразу несколько лишних команд в цикле // Цикл заполнения пробелами не более, чем 4x ,байтиков. А как это на 32битниках, тем более на // Cortex это можно сделать одной командой?( ну ладно двумя - одна регистр пробелами заполняет) Sign - а как же без него, он же потом используется, в пока не известном месте. 32 бита - согласен. Согласен понести наказание (вернее, уже понес :)) push/pop - разве они там есть? Массивы вместо указателей - не уверен, не исключаю что в данном случае это одно и то же. Заполнение пробелами - их может быть разное количество, здесь 32-битовые слова не помогут. Над этим подумаю... Докладываю - создал тестовый проект, в котором только itoa, компилятор задействовал SDIV. Возрадуемся, братья! :) 2 aaarrr Про формат 4.28 - что это, где почитать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба Sign - а как же без него, он же потом используется, в пока не известном месте. Можно с большей пользой использовать регистр, например, взять и скопировать в него Ваш 'Number'. При этом будете работать с этим 32bit, а не 16ише, а плюсики и прочее рисовать потом по 'Number' push/pop - разве они там есть? Напихаете разных переменных - будут. Массивы вместо указателей - не уверен Ну-ну... Две переменных, вместо одной. Заполнение пробелами - их может быть разное количество, здесь 32-битовые слова не помогут. Помогут, помогут - заполняйте до того, как начнете цифирки заносить. Возрадуемся, братья! :) Чему? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба 2 aaarrr Про формат 4.28 - что это, где почитать? Не надо про него читать, просто 4 старших бита - целая часть, остальные - дробная. Довольно часто используется в виде 1.31 или 1.15 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 июня, 2010 Опубликовано 26 июня, 2010 · Жалоба Спасибо всем! На сегодня и завтра - умолкаю. "Работа над ошибками". Возрадуемся - что в Cortex есть команда деления, которая иногда используется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 27 июня, 2010 Опубликовано 27 июня, 2010 · Жалоба Возрадуемся - что в Cortex есть команда деления, которая иногда используется. Ещё как используется. На днях посмотрел, для интереса, как скомпилировались операции (dword / 10) и, следом за ней, (dword % 10). В первом случае, естественно, UDIV. А во втором - MLS (Multiply and Subtract) с использованием результата предыдущего вычисления. Есть такая хитрая и полезная (как раз для этих целей) команда :) Так что даже не пришлось делать вычитание ручками, RealView сам всё оптимизирует правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 27 июня, 2010 Опубликовано 27 июня, 2010 · Жалоба Так что применение div и тут в два раза сокращает затраты времени на деление по сравнению с раздельной парой /, %. Оптимизатор сам не видит, что можно было бы вызвать еление один раз.Я видел заплатку для этого случая. Сейчас gcc ИМХО это видит:-) To ViKo: Поделитесь насколько itoa будет медленнее Вашего самого лучшего варианта:-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
badik 0 28 июня, 2010 Опубликовано 28 июня, 2010 · Жалоба Господа всем огромный привет, ни как не думал, что моя маленькая проблема вызовет такой мощный отклик. Вот уж точно 100 друзей намного лучше.. Тут уважаемые "Местный" и "воинствующий философ" подсказали простое решение sprintf, посмотрел С Шилдта с примером, у меня всё идеальо сработало. Если не затруднил - осмелюсь ещё поспрашать столь почтенное сообщество. Я в начале ADSP-BF533, BF548 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться