Сынулька в подобных ситуациях всегда подкалывает меня цитатой из этого ролика.
да я это видел, 512, 1024 и 2048
Всё, выходи. И да начнется жатва…
Наданапицца.
А я подумал, что ты “уже” ))
Пока нет, у мня еще сонца не село
как я Вам уже говорил, мне надоела Ваша клоунада про ассемблер, но Вы проигнорировали мою просьбу прекратить. Давайте поступим так, я предлагаю Вам
Джентльменское пари
Присутствующие коллеги будут судьями.
Суть пари: Вы пишете функцию для вычисления чисел Фибоначчи на ассемблере (вставкой в С++ или отдельным файлом, как Вам удобнее), А я пишу функцию для того же на С++. Затем мы запускаем вот такой
тест
//
// Здесь функция Fib, считающая числа Фибоначчи
// Fib(0) = 0
// Fib(1) = 1
// Fib(n) = Fib(n-1) + Fib(n-2) (при 1 < n < 25)
// Fib(n) = 0xFFFF (при n > 24)
//
// .......
void setup(void) {
Serial.begin(9600);
const uint32_t start = micros();
const uint16_t result = Fib(24);
const uint32_t duration = micros() - start;
Serial.print("F(24)=");
Serial.println(result);
Serial.print("Время: ");
Serial.print(duration);
Serial.println(" us");
}
void loop(void) {}
И сравниваем размер памяти (программы и данных) и быстродействие (время расчёта). Если показатели моей функции лучше (по мнению судей), то Вы затыкаетесь и больше ни слова про преимущества ассемблера здесь не вещаете. Если же проиграю я, то я затыкаюсь и больше никак не критикую и не обсуждаю Ваши перлы про ассемблер.
Формальные условия:
- Тестовая программа как приведена – только добавить функцию вычисления чисел Фибоначчи;
- MCU – ATmega328P;
- среда компиляции скетча – Arduino IDE 2.2.1 с опциями «из коробки», т.е. чистая установка безо всяких подкручиваний;
- Каждый участник выкладывает свой скетч в полном виде, чтобы любой желающий мог запустить его у себя и сверить результаты.
- Время на написание функции назначьте сами. Я готов написать нс С++ на пару минут.
Формальное определение требуемой функции:
- Тип возвращаемого значения –
uint16_t
- Один параметр типа
uint8_t
может принимать значения от 0 до 24 включительно (при большем параметре результат не влезет вuint16_t
) - Функция должна возвращать:
Fib(0) = 0
Fib(1) = 1
Fib(n) = Fib(n-1) + Fib(n-2); (при 1 < n < 25)
Fib(n) = 0xFFFF; (при n > 24) – это будет признаком ошибки в параметре
Кстати, результат приведённого выше теста – 46368 (это легко проверить вручную)
кстати
Обратите внимание, я специально выбрал задачу в которой используются только операции целочисленного сложения, чтобы не устраивать для Вас весёлую жизнь с умножениями плавающих чисел, как тут предлагали - цените.
Ну, как, согласны на деле продемонстрировать преимущества ассемблера? Или только языком можете?
А можно на чём то типа 1.18… портативном ? Не хочу пачкать комп … 2… версиями. (или в wokwi.com)
У меня вот так получилось )))
Спойлер
//
// Здесь функция Fib, считающая числа Фибоначчи
// Fib(0) = 0
// Fib(1) = 1
// Fib(n) = Fib(n-1) + Fib(n-2) (при 1 < n < 25)
// Fib(n) = 0xFFFF (при n > 24)
//
// .......
uint16_t Fib (uint8_t num);
void setup(void) {
Serial.begin(9600);
const uint32_t start = micros();
const uint16_t result = Fib(20);
const uint32_t duration = micros() - start;
Serial.print("F(24)=");
Serial.println(result);
Serial.print("Время: ");
Serial.print(duration);
Serial.println(" us");
}
void loop(void) {
}
uint16_t Fib (uint8_t num) {
if (num == 0) return 0;
if (num == 1) return 1;
if (num > 24) return 0xFFFF;
return Fib (num - 1) + Fib (num - 2);
}
Результаты в Wokwi:
//===================
F(24)=46368
Время: 187288 us
//===================
F(15)=610
Время: 2464 us
А память?
У меня в Wokwi время всегда 0 … видимо я что то делаю не так …
F(24)=46368
Время: 0 us
F(15)=610
Время: 0 us
uint16_t Fib (uint8_t num) {
const uint16_t f[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368};
return num > 24 ? 0xffff : f[num];
}
void setup(void) {
Serial.begin(9600);
const uint32_t start = micros();
const uint16_t result = Fib(24);
const uint32_t duration = micros() - start;
Serial.print("F(24)=");
Serial.println(result);
Serial.print("Время: ");
Serial.print(duration);
Serial.println(" us");
}
void loop(void) {}
1.18.19
скетч @BOOM
Скетч использует 1924 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 212 байт (10%) динамической памяти, оставляя 1836 байт для локальных переменных. Максимум: 2048 байт.
скетч @Komandir
Скетч использует 1862 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 212 байт (10%) динамической памяти, оставляя 1836 байт для локальных переменных. Максимум: 2048 байт.
Давайте уже ваш вариант - запущу у себя и опубликую результат для статистики ?
При настолько ограниченном значении входного параметра - это слишком неудачная функция.
Вам шашечки или ехать ???
Но не для всемогущего ассемблера ведь? ))
Сдаётся мне, что всё это на этапе оптимизации схлопывается до:
void setup(void) {
Serial.begin(9600);
// const uint32_t start = micros();
// const uint16_t result = Fib(24);
// const uint32_t duration = micros() - start; // => micros() - micros();
Serial.print("F(24)=");
Serial.println(46368);
Serial.print("Время: ");
Serial.print(0);
Serial.println(" us");
}
У меня то не “схлопывается”.
Про успехи компилятора в условиях не было ничего !!!
Пусть @ЕвгенийП изменит основную часть и сделает прогон от 0 до 25 с расчётом общего времени, тогда уже компилятору буде сложнее что то отбросить …
так, а чего Вы ожидали с такой программой? micros() меняется через 4 мкс (это её шаг), а вот эта Ваша функция работает явно меньше 4 мкс. Всё у Вас правильно, правда константы я не проверял.