Время на исполнение разных функций

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Провел тесты на вермя исполнения разных функций

тестировал таким кодом. менял только функции и типы данных. иногда значения

unsigned long time;
int i = 150;
int z = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  time = micros();
  z = map(i, 0, 255, 0, 200);
  
  Serial.println(micros()-time);
}

i в основном не меняется и равно 150. пишу значение которое чаще всего повторяется. 

плата arduino micro 16МГц

map

int i = 150; 
int z;

z = map(i, 0, 1023, 0, 255); 64мкс

z = map(i, 0, 255, 0, 200);   56мкс

byte i = 150;
byte z = 0;

z = map(i, 0, 1023, 0, 255); 54мкс

z = map(i, 0, 255, 0, 200);  56мкс

constrain

z = constrain(i, 100, 200); 4мкс
z = constrain(i, 180, 200); 4мкс

sin

z = sin(i);  132мкс

cos

z = cos(i); 124мкс

умножение

z = i*i;                         4мкс
z = 63000*63000;    4мкс
z = 2000000000*2;  4мкс

тут я думал будет больше

деление

z = i/30;                               20мкс


long i = 4000000000;
long z = 6000000;
z = i/z;;                                 48мкс

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

float 

умножение 

unsigned long time;
float i = 210.584;
float z = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  time = micros();
  z = i*i;
  
  Serial.println(micros()-time);
}

12мкс

деление

unsigned long time;
float i = 210.584;
float z = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  time = micros();
  z = i/12.521;
  
  Serial.println(micros()-time);
}

36мкс

Клапауций
Offline
Зарегистрирован: 10.02.2013

попробуй

unsigned long time_start;
unsigned long time_stop;
float z = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  time_start = micros();
  z = 210.584*210.584
  time_stop = micros();
  Serial.println(time_stop - time_start);
}

изменится ли время выполнения?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да изменилось. получилось 4мкс

но так как обычно перемножаются объявленные переменные то сделал так

unsigned long time_start;
unsigned long time_stop;
float i = 210.584;
float z = 0;

void setup(){
  Serial.begin(9600);
}

void loop(){
  time_start = micros();
  z = i*i;
  time_stop = micros();
  Serial.println(time_stop - time_start);
}

получились теже 12мкс

Клапауций
Offline
Зарегистрирован: 10.02.2013

интересная тема - можно реально тестировать варианты кода на скорость выполнения.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну и всеми любимый вольтметр на ардуине

#define ADC A0
float voltage;
unsigned long time;

void setup() {
  Serial.begin(9600);
}

void loop() {
  time = micros();
  voltage = analogRead(ADC) * (5.0 / 1023.0);
  Serial.println(micros()-time);
}

128мкс

предлагайте варианты. буду проверять

Клапауций
Offline
Зарегистрирован: 10.02.2013

jeka_tm пишет:

предлагайте варианты. буду проверять

да - сами у себя бум проверять.

то я тебя попросил потому, что первый результат на твоём железе был замерен.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну да. только интересная вещь. в 32u4 аппаратный USB и отсылает он в сериал намного чаще чем таже UNO например. везде скорость 9600. странно это

делитесь результатами. будем знать

+ хотя нет. ошибочка вышла. там код был больше и сложилось такое впечатление

проверил последний на uno теже 128мкс

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

кстати значения скачут периодически немного на обих платах. с чем связано хз

Клапауций
Offline
Зарегистрирован: 10.02.2013

твой амперметр на меге16-й 12МГц - 155-160.

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

unsigned long time_start;
unsigned long time_stop;

float voltage;

void setup() {lcd.begin(16, 2);}

void loop() {
time_start = micros();
voltage = analogRead(0) * (5.0 / 1023.0);
time_stop = micros();
//lcd.clear();
lcd.setCursor(0, 0);
lcd.print(time_stop - time_start);
}

*нужно учитывать, что получаемые значения будут кратны 4-м при частоте 16МГц(у меня на 12-ти - кратны 5-ти), поэтому особой точности на малых значениях добиться не удастся.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

позже как нибудь проверю на меге 8мгц. около 200 должно наверно получится

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

потестил максимальную частоту обновления экрана 1202 ногодрыганьем напрямую через управление портом. 

плата ардуино уно

заливал весь экран белым измерял сколько заняло времени, и также черным

вот результаты

8412 mks  118 Hz
8844 mks  113 Hz
8412 mks  118 Hz
8852 mks  112 Hz
8412 mks  118 Hz
8848 mks  113 Hz
8412 mks  118 Hz
8844 mks  113 Hz
 
затем решил что лучше 1000 раз например обновить экран и посчитать среднее
 
вот что получилось
 
8802 mks  113 Hz
 
 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

1.8" Serial SPI TFT LCD Module Display

потестил частоту обновления дисплея

http://www.ebay.com/itm/1-8-Serial-SPI-TFT-LCD-Module-Display-PCB-Adapter-Power-IC-SD-Socket-128X160-/190920594011?pt=AU_B_I_Electrical_Test_Equipment&hash=item2c73c1125b

андуина уно 16мгц

программный SPI (ногодрыганье)

0,64 кадра/с

1572 мс один кадр

хардварный SPI

6,25 кадров/с

160 мс один кадр

с хардварным намного быстрее, но все равно медленно. попробую покромсать либу для увеличения FPS.

большого ускорения это не даст, только увеличение частоты сильно поможет

+ изменив делитель SPI до минимального 2 получилось немного быстрее (тут уже и далее если буду тестить только хардварный)

8.40 кадров/с
119 мс один кадр
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

1.8" Serial SPI TFT LCD Module Display

продолжение

помучав еще библиотеку и перелопатив ее увеличил еще скорость

14.49 кадров/с
70 мс один кадр
 
программно уже не вижу что можно ускорить. если и найду что нибудь все равно сильной прибавки не даст. 
тут только тактовую повышать, или переходить на дисплеи с паралельным интерфейсом (скоро такой буду пробовать)
 
 
 
selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

jeka_tm пишет:

хардварный SPI

как   он использовался  ?

 на дисплее  9 бит SPI а в мегах только 8 бит длина пакета

или    аппаратно передаётся 8,затем 1 бит в  ручную ?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

первый бит вручную, отстальные хардварно

именно первый вручную потому что 1 бит задает тип данных: команда или данные, а затем сами данные

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

а код есть где-то ?

может  кому-то пригодится

и мне интересно

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

http://yadi.sk/d/CXjuENmaEEwun

папка дисплеи

Adafruit_ST7735.zip

доп. пины для дисплея забиты на 9 и 10 пины ардуины

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

хорошо,благодарю.

а для  1202 какая  заготовка использовалась ?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

в смысле заготовка?

releyshic
Offline
Зарегистрирован: 20.11.2015

Serial то наверно прилично сам сьедает ))

axill
Offline
Зарегистрирован: 05.09.2011

Интересно какие настройки оптимизации в ардуине использованы. Ведь в avr-gcc который использует ардуино есть несколько вариантов оптимизации в том числе на скорость

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Нормальный компилятор, когда увидит во многих из приведённых примеров, что переменная не изменяется, вычислит её на этапе компиляции и - всё. Чего меряем-то? Сферического коня в вакууме?

З.Ы. Если что - это про подобные вещи:

z = constrain(i, 100, 200)

float i = 210.584;
z = i*i;

map, constrain - это вообще препроцессорные директивы, их можно вычислить на этапе компиляции. i - не меняется, и смело можно вычислить на этапе компиляции, чему будет равна z. Так что замеренные величины - это промежуток между двумя отработками функции micros, я подозреваю. Короче, доверять таким "тестам" совсем не стоит.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Верно. Время исполнения micros() 3.5мксек .. можно улучшить до 2.5 .. но все равно оно будет кратно 4мксек. Чтобы такие вещи проверять надо сначала "обмануть" компилятор или отменить ему оптимизацию, а потом делать замеры в длинном цикле и усреднять по количеству повторов.

По мат. функциям времена исполнения есть в описании на glibc .. и там совсем иные чиселки. (может просто надо читать RTFM?) :)