|
|
  |
Вопрос С |
|
|
|
Jun 26 2010, 10:24
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Следуя рекомендациям, слегка модернизировал код. Код 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, который чуть выше в файле лежит. Только написан на ассемблере. Цитата(zltigo @ Jun 26 2010, 12:18)  Посему повторяю рекомендации откомпилировать и посмотреть на результат с / % для всех ранее помянутых ядер. Так-же напомню, что слово "гуано" относилось далеко не только к использованию / %. Для всех ядер - это вы уж слишком многого от меня хотите.  У меня и компиляторов таких нет. А для Cortex-M3 я написал и откомпилировал, и из ваших высказываний так и не понял, что бы такого можно было улучшить в моем коде. А примера, как надо делать, вы не привели.
|
|
|
|
|
Jun 26 2010, 11:31
|
Частый гость
 
Группа: Участник
Сообщений: 95
Регистрация: 22-01-09
Пользователь №: 43 819

|
Цитата(ViKo @ Jun 26 2010, 14:24)  Следуя рекомендациям, слегка модернизировал код. вы бы озвучили с какой целью модифицировался код. надо "быстрый алгоритм", "короткий код", "читаемый текст" или еще что-то? Нужен быстрый и не требовательный алгоритм - в atoi_v1. слишком длинное решение - посмотрите в atoi_v2. Операции деления отсутствуют как класс. P.S. тексты в файлах - написаны за 2 минуты и на работоспособность не проверялись. демонстрируется метод табличного решения задачи. ничего более. P.P.S. метод имеет смысл применять на простых контроллерах без аппаратного умножителя. (с умножителем надо думать). Сергей.
Сообщение отредактировал ssvSerge - Jun 26 2010, 11:36
|
|
|
|
|
Jun 26 2010, 14:19
|
Частый гость
 
Группа: Участник
Сообщений: 95
Регистрация: 22-01-09
Пользователь №: 43 819

|
Цитата(ViKo @ Jun 26 2010, 16:55)  В алгоритмах число записывается задом наперед и нет индикации знака числа. кроме этого нет проверки на 0 и в одном из разрядов нет проверки на "bIsDigitPresent". Это если уж быть точным. Но это мелочи - код и не претендовал на работоспособность. Главное, что подход понятен. Цитата(ViKo @ Jun 26 2010, 16:55)  код сделать лучше, оптимальнее. Слово "оптимальнее" следует исключить из лексикона как антинаучное. Есть критерии: скорость, объем, читабельность и т.д. Для каждого человека, проекта, процессора критерии изменяются. Цитата(ViKo @ Jun 26 2010, 16:55)  В идеале - оптимальнее и по производительности, и по компактности. ну так озвучьте цифры какой из вариантов (табличный или с делениями) оптимальнее в конкретно вашем случае. на ваших процессорах и в ваших глазах. Сергей.
|
|
|
|
|
Jun 26 2010, 14:42
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(ssvSerge @ Jun 26 2010, 17:19)  ну так озвучьте цифры какой из вариантов (табличный или с делениями) оптимальнее в конкретно вашем случае. на ваших процессорах и в ваших глазах. В данный момент меня занимает алгоритм от aaarrr, поискал по компу своему книжку по цифровые трюки, но не нашел. А ведь была. Нельзя ли его расширить, чтобы принимал все числа. Второй вариант - преобразовать bin в BCD, а затем уже превратить в строку. Табличный способ меня не привлекает из-за громоздкости. Точные цифры по быстродействию и размеру кода я не смотрел. Если будет что сказать, доложу. P.S. Определился, пожалуй, что для меня значит оптимальность. = Компактность кода. А быстродействие мне STM32 и так обеспечит. P.P.S. Причем, часто бывает, что компактный код и работает быстро.
|
|
|
|
|
Jun 26 2010, 15:05
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (ViKo @ Jun 26 2010, 13:24)  Для всех ядер - это вы уж слишком многого от меня хотите.  У меня и компиляторов таких нет. Тем не менее, Вы уже второй раз утверждаете, что писали с оглядкой на Cortex? Лично я воспринял это, как то, что Вы знаете, что творите. QUOTE из ваших высказываний так и не понял, что бы такого можно было улучшить в моем коде. Хорошо,не затрагивая, так сказать основ, только то, что сразу режет глаз. CODE 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] = ' '; }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 26 2010, 15:12
|
Частый гость
 
Группа: Участник
Сообщений: 95
Регистрация: 22-01-09
Пользователь №: 43 819

|
Цитата(ViKo @ Jun 26 2010, 18:42)  для меня оптимальность = Компактность кода. бывает, что компактный код и работает быстро. о - вот теперь всё понятно. табличные методы в таких условиях, конечно, проигрывают. я хотел сказатать только, что таблицу можно сделать на базе "2 в степени" и заниматься BCD сложением. Значительно компактнее, чем десятичная таблица, и реализация на ASM проста до смешного. Хотя в скорости, конечно, уступает десятичной. Сергей.
|
|
|
|
|
Jun 26 2010, 16:28
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(zltigo @ Jun 26 2010, 18:05)  // Зачем-то завели малополезную переменную 'Sign' // Cortex говорите? Тогда за не 32 bit переменные, где в этом нет // небходимости по рукам надо давать. Да и сама переменная лишняя - только команд ush/pop добавляет // А за использование "массивов" вместо указателей - еще один раз // 32 bit контроллер? Тогда зачем его беднягу опять без всякой надобности // заставлять с 16bit 'Number' работать? Сразу несколько лишних команд в цикле // Цикл заполнения пробелами не более, чем 4x ,байтиков. А как это на 32битниках, тем более на // Cortex это можно сделать одной командой?( ну ладно двумя - одна регистр пробелами заполняет) Sign - а как же без него, он же потом используется, в пока не известном месте. 32 бита - согласен. Согласен понести наказание (вернее, уже понес  ) push/pop - разве они там есть? Массивы вместо указателей - не уверен, не исключаю что в данном случае это одно и то же. Заполнение пробелами - их может быть разное количество, здесь 32-битовые слова не помогут. Над этим подумаю... Докладываю - создал тестовый проект, в котором только itoa, компилятор задействовал SDIV. Возрадуемся, братья!  2 aaarrr
Про формат 4.28 - что это, где почитать?
|
|
|
|
|
Jun 26 2010, 16:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (ViKo @ Jun 26 2010, 19:28)  Sign - а как же без него, он же потом используется, в пока не известном месте. Можно с большей пользой использовать регистр, например, взять и скопировать в него Ваш 'Number'. При этом будете работать с этим 32bit, а не 16ише, а плюсики и прочее рисовать потом по 'Number' QUOTE push/pop - разве они там есть? Напихаете разных переменных - будут. QUOTE Массивы вместо указателей - не уверен Ну-ну... Две переменных, вместо одной. QUOTE Заполнение пробелами - их может быть разное количество, здесь 32-битовые слова не помогут. Помогут, помогут - заполняйте до того, как начнете цифирки заносить. QUOTE (ViKo @ Jun 26 2010, 19:28)  Возрадуемся, братья!  Чему?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 27 2010, 17:02
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(ViKo @ Jun 26 2010, 21:00)  Возрадуемся - что в Cortex есть команда деления, которая иногда используется. Ещё как используется. На днях посмотрел, для интереса, как скомпилировались операции (dword / 10) и, следом за ней, (dword % 10). В первом случае, естественно, UDIV. А во втором - MLS (Multiply and Subtract) с использованием результата предыдущего вычисления. Есть такая хитрая и полезная (как раз для этих целей) команда  Так что даже не пришлось делать вычитание ручками, RealView сам всё оптимизирует правильно.
|
|
|
|
|
Jun 27 2010, 18:51
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(ReAl @ Jun 26 2010, 13:04)  Так что применение div и тут в два раза сокращает затраты времени на деление по сравнению с раздельной парой /, %. Оптимизатор сам не видит, что можно было бы вызвать еление один раз. Я видел заплатку для этого случая. Сейчас gcc ИМХО это видит:-) To ViKo: Поделитесь насколько itoa будет медленнее Вашего самого лучшего варианта:-)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 28 2010, 17:43
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 29-11-06
Из: Екатеринбург
Пользователь №: 22 890

|
Господа всем огромный привет, ни как не думал, что моя маленькая проблема вызовет такой мощный отклик. Вот уж точно 100 друзей намного лучше.. Тут уважаемые "Местный" и "воинствующий философ" подсказали простое решение sprintf, посмотрел С Шилдта с примером, у меня всё идеальо сработало. Если не затруднил - осмелюсь ещё поспрашать столь почтенное сообщество. Я в начале ADSP-BF533, BF548
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|