реклама на сайте
подробности

 
 
> Временные интервалы
Andruxa-1
сообщение Jun 21 2010, 08:55
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 28-05-10
Пользователь №: 57 586



Я задействовал таймер1, прерывание по переполнению. Таймер служит для подсчета тиков ну и вычисления системного времени. Внешний кварц на 20 Мгц. Можно ли оптимизировать вычисления.
CODE
#include <avr\io.h>
#include <avr\interrupt.h>

uint32_t ulSystemTime = 0;
uint32_t ulTmp;

void SistemTimerInit(){
TCCR1A = 0;
TIMSK |= (1<<TOIE1);
TCCR1B |= (1<<CS10);
}

uint32_t GetSystemTimeMS(){
cli();

ulTmp = (ulSystemTime<<16) + TCNT1;

sei();

return (ulTmp);
}

SIGNAL(SIG_OVERFLOW1)
{
cli();

ulSystemTime++;

sei();
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
xemul
сообщение Jun 22 2010, 16:18
Сообщение #2



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Завести таймер на 5 мкс, в его прерывании делать только
Код
PORTC = tmpC;
Flag_5us = 1;

В основном цикле
Код
uint24_t ch1_cnt, ..., ch8_cnt; // uint24_t придумать, для счётчиков при 0.1 Гц и 5 мкс нужен 21 бит
                                // с uint32_t будут лишние считания
if(Flag_5us)
{
   if(!--ch1_cnt) { tmpC ^= 1; ch1_cnt = (tmpC & 1)? ch1_high_time: ch1_low_time; }
   if(!--ch2_cnt) { tmpC ^= 2; ch2_cnt = (tmpC & 2)? ch2_high_time: ch2_low_time; }
...
   if(!--ch8_cnt) { tmpC ^= 128; ch8_cnt = (tmpC & 128)? ch8_high_time: ch8_low_time; }
   Flag_5us = 0;
}

Но в 5 мкс (100 тактов на 20 МГц) if(Flag_5us) {...} всё равно не уложится, так что урезайте осетра по разрешению.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 24 2010, 22:35
Сообщение #3


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(xemul @ Jun 22 2010, 15:18) *
Завести таймер на 5 мкс, в его прерывании делать только
Код
PORTC = tmpC;
Flag_5us = 1;

В основном цикле
Код
uint24_t ch1_cnt, ..., ch8_cnt; // uint24_t придумать, для счётчиков при 0.1 Гц и 5 мкс нужен 21 бит
                                // с uint32_t будут лишние считания
if(Flag_5us)
{
   if(!--ch1_cnt) { tmpC ^= 1; ch1_cnt = (tmpC & 1)? ch1_high_time: ch1_low_time; }
   if(!--ch2_cnt) { tmpC ^= 2; ch2_cnt = (tmpC & 2)? ch2_high_time: ch2_low_time; }
...
   if(!--ch8_cnt) { tmpC ^= 128; ch8_cnt = (tmpC & 128)? ch8_high_time: ch8_low_time; }
   Flag_5us = 0;
}

Но в 5 мкс (100 тактов на 20 МГц) if(Flag_5us) {...} всё равно не уложится, так что урезайте осетра по разрешению.

Тогда уж лучше весь if(Flag_5us) {...} вставить в прерывание, по крайней мере, флаг не придётся проверять. Но прерывание для данной задачи - зло, поэтому лучше делать без прерываний вообще, не будет потерь времени на сохранение контекста в прерывании.

Конструкция if(!--ch1_cnt) ... выглядит компактно, но только на бумаге, здесь 8 раз вычитается то, что в предыдущем решении таймер1 делает аппаратно.

По моим грубым прикидкам, если писать на асме, то можно уложиться в максимальный джиттер 8 мкс.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
xemul
сообщение Jun 25 2010, 10:07
Сообщение #4



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(=GM= @ Jun 25 2010, 02:35) *
Тогда уж лучше весь if(Flag_5us) {...} вставить в прерывание, по крайней мере, флаг не придётся проверять. Но прерывание для данной задачи - зло, поэтому лучше делать без прерываний вообще, не будет потерь времени на сохранение контекста в прерывании.

Я затруднюсь сказать, что лучше, не видя остальной части загадки. Потери на общение с волатильными счетчиками могут оказаться больше и непредсказуемей.
Цитата
Конструкция if(!--ch1_cnt) ... выглядит компактно, но только на бумаге, здесь 8 раз вычитается то, что в предыдущем решении таймер1 делает аппаратно.

Я предложил "рыбу" решения на С - так короче. имхо, исходно было понятно, что отдавать оптимизацию компилятору в этой задаче ... неразумно.
Извините, не понял, какое из предыдущих решений Вы имели в виду.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 25 2010, 11:30
Сообщение #5


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Из поста #26.

1) Ну смотрите, объясняю конструкцию if(!--ch1_cnt) на пальцах. Надо загрузить 4-х байтный счётчик из памяти в регистры, вычесть 1 и сохранить обратно в памяти. И так 8 раз!

2) В прерывании вы выставляете флаг5мкс, а в фоне ждёте его. Если поместить тело if в прерывание, то ждать флага не надо, наступило прерывание - выполняем тело if. Всяко быстрее будет.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
xemul
сообщение Jun 25 2010, 12:46
Сообщение #6



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(=GM= @ Jun 25 2010, 15:30) *
Из поста #26.

1) Ну смотрите, объясняю конструкцию if(!--ch1_cnt) на пальцах. Надо загрузить 4-х байтный счётчик из памяти в регистры, вычесть 1 и сохранить обратно в памяти. И так 8 раз!

За объяснение спасибо. Я об этом смутно догадывался, Вы подтвердили мои опасения.smile.gif
В посте #26 в любой ветке выполняется 3 бинарные (!) операции с uint32_t (две из них - с загрузкой и сохранением). И так 8 раз!
Изначально (мной) было сказано, что достаточно 3 байтов на счётчик, с соответствующими умолчательными предположениями о реализации и оптимизации.
Декремент 3-х (или 4-х) байтового числа с проверкой на 0, имхо, не сложнее if(sysTime>endTime[i]), которая выполняется через вычитание двух uint32_t и проверку знака результата.
Цитата
2) В прерывании вы выставляете флаг5мкс, а в фоне ждёте его. Если поместить тело if в прерывание, то ждать флага не надо, наступило прерывание - выполняем тело if. Всяко быстрее будет.

Вряд ли - только на сохранении/восстановлении регистровой пары в прерывании будет потеряно столько же. В качестве же бесплатного довеска - некоторое количество volatile uint32_t с сопутствующим оверхедом.
Ну и скорость в данном месте как-то сбоку - на джиттер не влияет, а если у контроллера не хватит скорострельности, то абсолютно фиолетово, где не хватит - в прерывании или в фоне.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 25 2010, 15:56
Сообщение #7


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Немного повергло в шок, как компилятор WinAVR транслирует вашу конструкцию
Код
//HEMUL VERSION
  if(!--endTime0)
19c:    8d 81           ldd    r24, Y+5; 0x05
19e:    9e 81           ldd    r25, Y+6; 0x06
1a0:    af 81           ldd    r26, Y+7; 0x07
1a2:    b8 85           ldd    r27, Y+8; 0x08
1a4:    01 97           sbiw    r24, 0x01; 1
1a6:    a1 09           sbc    r26, r1
1a8:    b1 09           sbc    r27, r1
1aa:    8d 83           std    Y+5, r24; 0x05
1ac:    9e 83           std    Y+6, r25; 0x06
1ae:    af 83           std    Y+7, r26; 0x07
1b0:    b8 87           std    Y+8, r27; 0x08
1b2:    8d 81           ldd    r24, Y+5; 0x05
1b4:    9e 81           ldd    r25, Y+6; 0x06
1b6:    af 81           ldd    r26, Y+7; 0x07
1b8:    b8 85           ldd    r27, Y+8; 0x08
1ba:    00 97           sbiw    r24, 0x00; 0
1bc:    a1 05           cpc    r26, r1
1be:    b1 05           cpc    r27, r1
1c0:    81 f4           brne    .+32    ; 0x1e2 <main+0x166>
  {
   PINC =_BV(0);
1c2:    73 bb           out    0x13, r23; 19
   endTime0 =(PORTC & _BV(0))? tLow0 : tHigh0;
1c4:    a8 9b           sbis    0x15, 0; 21
1c6:    05 c0           rjmp    .+10    ; 0x1d2 <main+0x156>
1c8:    8d 85           ldd    r24, Y+13; 0x0d
1ca:    9e 85           ldd    r25, Y+14; 0x0e
1cc:    af 85           ldd    r26, Y+15; 0x0f
1ce:    b8 89           ldd    r27, Y+16; 0x10
1d0:    04 c0           rjmp    .+8     ; 0x1da <main+0x15e>
1d2:    89 89           ldd    r24, Y+17; 0x11
1d4:    9a 89           ldd    r25, Y+18; 0x12
1d6:    ab 89           ldd    r26, Y+19; 0x13
1d8:    bc 89           ldd    r27, Y+20; 0x14
1da:    8d 83           std    Y+5, r24; 0x05
1dc:    9e 83           std    Y+6, r25; 0x06
1de:    af 83           std    Y+7, r26; 0x07
1e0:    b8 87           std    Y+8, r27; 0x08
  }

Но по зрелому размышлению понял, что лучше и не сделаешь.

Странно, но вот так: if(!endTime0--) получается фрагмент на 4 такта быстрее.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 28 2010, 17:14
Сообщение #8


неотягощённый злом
******

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



Цитата(=GM= @ Jun 25 2010, 19:56) *
Немного повергло в шок, как компилятор WinAVR транслирует вашу конструкцию
endTime0 волатильный? Если да то нормально скомпилировал...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 28 2010, 22:08
Сообщение #9


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(demiurg_spb @ Jun 28 2010, 16:14) *
endTime0 волатильный? Если да то нормально скомпилировал...

Где ж нормально? Сохраняет регистры r24-r27 и тут же загружает ТЕ ЖЕ САМЫЕ РЕГИСТРЫ тем, что только что сохранил, ну не идиотизм? Уж не говорю о том, что операция 4-х байтного вычитания вырабатывает флаг Z, так что после std самое оно оставить только brne.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 29 2010, 11:48
Сообщение #10


неотягощённый злом
******

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



Цитата(=GM= @ Jun 29 2010, 02:08) *
Где ж нормально? Сохраняет регистры r24-r27 и тут же загружает ТЕ ЖЕ САМЫЕ РЕГИСТРЫ тем, что только что сохранил, ну не идиотизм? Уж не говорю о том, что операция 4-х байтного вычитания вырабатывает флаг Z, так что после std самое оно оставить только brne.
А я настаиваю:-), что для volatile фактически так и должно быть.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Andruxa-1   Временные интервалы   Jun 21 2010, 08:55
- - Палыч   По какому критерию Вы бы хотели провести оптимизац...   Jun 21 2010, 09:56
|- - Andruxa-1   этот кусок занимает 22 команды в дизасме ulTmp = (...   Jun 21 2010, 10:22
|- - MrYuran   Цитата(Andruxa-1 @ Jun 21 2010, 14:2...   Jun 21 2010, 10:28
||- - Andruxa-1   Цитата(MrYuran @ Jun 21 2010, 13:28) ...   Jun 21 2010, 10:32
||- - MrYuran   Цитата(Andruxa-1 @ Jun 21 2010, 14:3...   Jun 21 2010, 10:55
|- - Палыч   Цитата(Andruxa-1 @ Jun 21 2010, 14:2...   Jun 21 2010, 10:52
|- - Палыч   Цитата(Andruxa-1 @ Jun 21 2010, 14:2...   Jun 21 2010, 11:07
||- - Andruxa-1   Многоканальный генератор электрических импульсов п...   Jun 21 2010, 11:41
||- - MrYuran   Цитата(Andruxa-1 @ Jun 21 2010, 15:4...   Jun 21 2010, 11:47
|||- - Andruxa-1   Цитата(MrYuran @ Jun 21 2010, 14:47) Посч...   Jun 21 2010, 12:00
|||- - MrYuran   Цитата(Andruxa-1 @ Jun 21 2010, 16:0...   Jun 21 2010, 12:19
||- - Andruxa-1   ATMega8   Jun 21 2010, 12:36
||- - Палыч   Цитата(Andruxa-1 @ Jun 21 2010, 16:3...   Jun 21 2010, 12:51
||- - MrYuran   Цитата(Палыч @ Jun 21 2010, 16:51) Восемь...   Jun 21 2010, 15:23
|- - =GM=   Можно вот так оптимизировать Кодtt=GetSystemTimeMS...   Jun 21 2010, 15:26
|- - Andruxa-1   Цитата(=GM= @ Jun 21 2010, 18:26) Можно в...   Jun 22 2010, 10:02
|- - Палыч   Цитата(Andruxa-1 @ Jun 22 2010, 14:0...   Jun 22 2010, 11:00
|- - =GM=   Совершенно верно. Андрукса, какой у вас джиттер п...   Jun 22 2010, 11:26
|- - Andruxa-1   Цитата(=GM= @ Jun 22 2010, 14:26) Соверше...   Jun 22 2010, 12:32
|- - demiurg_spb   Цитата(Andruxa-1 @ Jun 22 2010, 16:3...   Jun 22 2010, 12:33
|- - =GM=   Цитата(Andruxa-1 @ Jun 22 2010, 11:3...   Jun 22 2010, 12:58
|- - Andruxa-1   Цитата(=GM= @ Jun 22 2010, 15:58) Похоже,...   Jun 22 2010, 13:13
|- - =GM=   Сути чего?   Jun 22 2010, 13:32
|- - Andruxa-1   Цитата(=GM= @ Jun 22 2010, 16:32) Сути че...   Jun 22 2010, 13:35
|- - =GM=   Ну, при программном подходе джиттер будет всегда, ...   Jun 22 2010, 15:24
|- - singlskv   Цитата(xemul @ Jun 22 2010, 20:18) uint24...   Jun 23 2010, 18:26
|- - xemul   Цитата(=GM= @ Jun 25 2010, 19:56) Но по з...   Jun 25 2010, 16:26
||- - =GM=   А зачем орить? После std сразу brne ... Но это не ...   Jun 25 2010, 21:05
||- - =GM=   Вот, немного переделал алгоритм if(sysTime>end...   Jun 28 2010, 12:12
|- - =GM=   Това-а-рищ Иванов, не надо настаивать на глупости ...   Jun 29 2010, 12:13
|- - demiurg_spb   Для волатильных объектов компилятор фактически не ...   Jul 1 2010, 10:07
- - Andruxa-1   Спасибо за ответы и подсказки, буду пробовать.   Jun 24 2010, 14:33
- - singlskv   Кстати, задачка на самом деле очень интересная, и ...   Jun 24 2010, 21:04
|- - Палыч   Цитата(singlskv @ Jun 25 2010, 01:04) Кст...   Jun 25 2010, 05:57
|- - singlskv   Цитата(Палыч @ Jun 25 2010, 09:57) Вот и ...   Jun 25 2010, 07:08
|- - MrYuran   Цитата(singlskv @ Jun 25 2010, 11:08) Вид...   Jun 25 2010, 07:18
|- - singlskv   Цитата(MrYuran @ Jun 25 2010, 11:18) Вы в...   Jun 25 2010, 07:24
- - MrYuran   В общем, если отбросить чисто академические изыски...   Jun 25 2010, 06:07
|- - =GM=   Цитата(MrYuran @ Jun 25 2010, 05:07) -В о...   Jun 25 2010, 09:12
- - XVR   ЦитатаЕстественно, можно было оптимизировать и не ...   Jul 2 2010, 06:22
- - demiurg_spb   Цитата(XVR @ Jul 2 2010, 10:22) Если комп...   Jul 2 2010, 12:45


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 15:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016