// sketch 04_01_benchmark
void setup()
{
Serial.begin(9600);
Serial.println("Starting Test");
long startTime = millis();
// Далее следует код тестирования
long i = 0;
long j = 0;
for (i = 0; i < 20000000; i ++)
{
j = i + i * 10;
if (j > 10) j = 0;
}
// конец кода, выполняющего тестирование
long endTime = millis();
Serial.println(j); // чтобы предотвратить оптимизацию цикла компилятором
Serial.println("Finished Test");
Serial.print("Seconds taken: ");
Serial.println((endTime — startTime) / 1000l);
}
void loop()
{
}
ПРИМЕЧАНИЕ
Версию программы на C для компьютера можно найти в разделе загрузки примеров на веб-сайте книги.
Вот какие результаты получились: на MacBook Pro с процессором 2,5 ГГц тестовая программа выполнялась 0,068 с, тогда как на Arduino Uno ей понадобилось 28 с. Плата Arduino оказалась примерно в 400 раз медленнее при решении данной задачи.
Сравнение плат Arduino
В табл. 4.1 показаны результаты выполнения этого теста в нескольких разных моделях платы Arduino.
Таблица 4.1. Результаты тестирования быстродействия Arduino
Модель | Время выполнения теста, с |
---|---|
Uno | 28 |
Leonardo | 29 |
Arduino Mini Pro | 28 |
Mega2560 | 28 |
Due | 2 |
Как видите, большинство моделей имеют схожую производительность, и только Due показала внушительный результат — она оказалась более чем в 10 раз быстрее остальных моделей.
Скорость арифметических операций
Для дальнейших исследований изменим только что использованный тест и вместо арифметики с длинными целыми протестируем быстродействие арифметики с вещественными числами. И те и другие занимают в памяти 32 бита, поэтому можно было бы ожидать, что время работы примера останется сопоставимым. В следующем тесте используем Arduino Uno.
// sketch 04_02_benchmark_float
void setup()
{
Serial.begin(9600);
while (! Serial) {};
Serial.println("Starting Test");
long startTime = millis();
// Далее следует код тестирования
long i = 0;
float j = 0.0;
for (i = 0; i < 20000000; i ++)
{
j = i + i * 10.0;
if (j > 10) j = 0.0;
}
// конец кода, выполняющего тестирование
long endTime = millis();
Serial.println(j); // чтобы предотвратить оптимизацию цикла компилятором
Serial.println("Finished Test");
Serial.print("Seconds taken: ");
Serial.println((endTime — startTime) / 1000l);
}
void loop()
{
}
К сожалению, с использованием вещественных чисел этот скетч выполняется намного дольше. Этот пример выполнялся в Arduino около 467 с вместо 28 с. То есть простая замена длинных целых чисел вещественными уменьшила скорость выполнения более чем в 16 раз. Справедливости ради следует заметить, что отчасти ухудшение обусловлено дополнительными операциями преобразования между значениями вещественных и целочисленных типов, которые также обходятся недешево в смысле времени выполнения.
Нужны ли вещественные числа в действительности?
Многие ошибочно полагают, что если измеряется такая характеристика, как температура, ее значение обязательно следует хранить в виде вещественного числа, потому что оно часто будет выражаться дробным числом, таким как 23,5. Вещественное число действительно может понадобиться, чтобы отобразить температуру, но ее необязательно хранить именно в таком виде.
Значения, прочитанные с аналоговых входов, имеют тип int, и на самом деле значимыми являются только 12 бит, что соответствует целым числам в диапазоне между 0 и 1023. При желании можно, конечно, сохранить эти 12 бит в 32-битном вещественном числе, но это никак не отразится на точности данных.
Значение, читаемое с датчика, может соответствовать, например, температуре в градусах Цельсия. Широко известный температурный датчик (TMP36) выводит напряжение, пропорциональное температуре. В скетчах, как показано далее, часто можно увидеть вычисления, преобразующие значение в диапазоне 0…1023, прочитанное с аналогового входа, в температуру в градусах Цельсия: