|
Временные интервалы |
|
|
|
Jun 21 2010, 08:55
|
Группа: Участник
Сообщений: 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(); }
|
|
|
|
|
 |
Ответов
|
Jun 22 2010, 16:18
|
    
Группа: Свой
Сообщений: 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) {...} всё равно не уложится, так что урезайте осетра по разрешению.
|
|
|
|
|
Jun 24 2010, 22:35
|

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 мкс.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 25 2010, 10:07
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(=GM= @ Jun 25 2010, 02:35)  Тогда уж лучше весь if(Flag_5us) {...} вставить в прерывание, по крайней мере, флаг не придётся проверять. Но прерывание для данной задачи - зло, поэтому лучше делать без прерываний вообще, не будет потерь времени на сохранение контекста в прерывании. Я затруднюсь сказать, что лучше, не видя остальной части загадки. Потери на общение с волатильными счетчиками могут оказаться больше и непредсказуемей. Цитата Конструкция if(!--ch1_cnt) ... выглядит компактно, но только на бумаге, здесь 8 раз вычитается то, что в предыдущем решении таймер1 делает аппаратно. Я предложил "рыбу" решения на С - так короче. имхо, исходно было понятно, что отдавать оптимизацию компилятору в этой задаче ... неразумно. Извините, не понял, какое из предыдущих решений Вы имели в виду.
|
|
|
|
|
Jun 25 2010, 12:46
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(=GM= @ Jun 25 2010, 15:30)  Из поста #26.
1) Ну смотрите, объясняю конструкцию if(!--ch1_cnt) на пальцах. Надо загрузить 4-х байтный счётчик из памяти в регистры, вычесть 1 и сохранить обратно в памяти. И так 8 раз! За объяснение спасибо. Я об этом смутно догадывался, Вы подтвердили мои опасения.  В посте #26 в любой ветке выполняется 3 бинарные (!) операции с uint32_t (две из них - с загрузкой и сохранением). И так 8 раз! Изначально (мной) было сказано, что достаточно 3 байтов на счётчик, с соответствующими умолчательными предположениями о реализации и оптимизации. Декремент 3-х (или 4-х) байтового числа с проверкой на 0, имхо, не сложнее if(sysTime>endTime[i]), которая выполняется через вычитание двух uint32_t и проверку знака результата. Цитата 2) В прерывании вы выставляете флаг5мкс, а в фоне ждёте его. Если поместить тело if в прерывание, то ждать флага не надо, наступило прерывание - выполняем тело if. Всяко быстрее будет. Вряд ли - только на сохранении/восстановлении регистровой пары в прерывании будет потеряно столько же. В качестве же бесплатного довеска - некоторое количество volatile uint32_t с сопутствующим оверхедом. Ну и скорость в данном месте как-то сбоку - на джиттер не влияет, а если у контроллера не хватит скорострельности, то абсолютно фиолетово, где не хватит - в прерывании или в фоне.
|
|
|
|
|
Jun 25 2010, 15:56
|

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 такта быстрее.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
Сообщений в этой теме
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       =GM= А зачем орить? После std сразу brne ... Но это не ... Jun 25 2010, 21:05      demiurg_spb Цитата(=GM= @ Jun 25 2010, 19:56) Немного... Jun 28 2010, 17:14       =GM= Цитата(demiurg_spb @ Jun 28 2010, 16:14) ... Jun 28 2010, 22:08        demiurg_spb Цитата(=GM= @ Jun 29 2010, 02:08) Где ж н... Jun 29 2010, 11:48         =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
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|