Отговори на тема  [ 17 мнения ]  Отиди на страница 1, 2  Следваща
Превъртащ се брояч 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение Превъртащ се брояч
Дайте да видим кой как е решил този често срещан проблем. :) Имаме превъртащ се брояч, размер 1 байт, стойности от 0 до 5, примерно. При достигане на 5 трябва да се нулира. Да кажем, че сме притиснати до стената и трябва да пестим всеки машинен цикъл. :wink: Няма ли начин да стане с 2-3 аритметични операции, без да се ползват усл. оператори?


Сря Фев 08, 2006 11:19 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Дек 19, 2004 6:26 pm
Мнения: 1628
Местоположение: Сливен
Мнение 
Аз обикновено го броя обратно - от 5 към 0 за да се ползва breq или brne
инструкции. А при 0 го зареждам с константата.
Така се избягва compare .
С аритметични операции не виждам как ще стане.


Сря Фев 08, 2006 11:30 am
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Вто Ное 01, 2005 10:23 am
Мнения: 704
Местоположение: Limerick, Ireland
Мнение 
count++;
count %=5;

_________________
"640 К са достатъчни на всеки за всичко."
Бил Гейтс


Сря Фев 08, 2006 11:57 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
nickich, знаеш ли %= за колко цикъла се изпълнява? [-X


Сря Фев 08, 2006 12:02 pm
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Вто Ное 01, 2005 10:23 am
Мнения: 704
Местоположение: Limerick, Ireland
Мнение 
bateAz, в интерес на истината не съм гледал какво генерира компилатора :oops:, но на С изглежда добре :lol:

_________________
"640 К са достатъчни на всеки за всичко."
Бил Гейтс


Сря Фев 08, 2006 12:21 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Май 27, 2005 1:32 pm
Мнения: 40
Местоположение: Sofia
Мнение 
В общия случай за N (но ако е допустимо броене назад вместо напред) няма по-прост начин от този, който предлага Wise. Иначе ако е задължително да се брои напред, не може да се избегне сравнението, условния преход и зареждането с по малък брой цикли. Все пак това са 3 инструкции.
Ако става дума за индекс към циркулярен буфер (най често за това ползваме такъв брояч) и ако имаме известна свобода да изберем дължина равна на точна степен на двойката, тогава ето какво е решението на Атмел (взето например от тяхната имплементация на UART управление с прекъсвания)

/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 128 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 128


#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif

#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif

И после вече е лесно, след инкрементиране на брояча правим counter &= UART_RX_BUFFER_MASK, което съдържа само единици. По просто от това не може.


Сря Фев 08, 2006 12:49 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
По принцип xor със себе си дава 0, ще се помъча да измисля нещо в тая насока.
Другото, което може да се използва, е възможността за директен jump към адрес при някои процесори, което в комбинация с обратното броене, предложено от Wise, също може да даде добър резултат.


Сря Фев 08, 2006 1:03 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Всички процесори имат инструкция Jump при 0. Така че наистина по оптимално от броенето назад невиждам.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Сря Фев 08, 2006 1:22 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 24, 2005 11:41 pm
Мнения: 1049
Местоположение: Pz
Мнение 
Цитат:
Аз обикновено го броя обратно - от 5 към 0 за да се ползва breq или brne
инструкции. А при 0 го зареждам с константата.
Така се избягва compare .
С аритметични операции не виждам как ще стане.

Точно... По-бързо и по-малко едва ли може да стане по друг начин


Сря Фев 08, 2006 6:03 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Юни 07, 2005 6:20 pm
Мнения: 3532
Мнение 
Ако трябва да брои напред (и ако) може да се ползва още един байт. Просто ще си брои назад по нормалния начин, а в допълнителния байт ще натрупва напред. Обаче инструкциите стават повечко.


Сря Фев 08, 2006 9:55 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение 
Ами зависи от поцесора, може да с еползва ако има флаг вдигащ се при пренос от FF към 0, или ако рзултата от операцията е нула, в тоя случай зреждаш допулнението до FF, но пак губиш възможността от директно ползване на брояча, т.е. стойността му няма да е реалния брой цикли.


Пет Фев 10, 2006 9:46 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Вече почвам да си мисля, че ако някой производител на микроконтролери я направи тази екстра с брояча хардуерно, ще спечели доста пари. :D В AVR-а (а предполагам и на други места) е направено, но само за таймерите.


Пет Фев 10, 2006 9:55 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
В i8051 има CJNE - с една инструкция: проверява дали операнд1 = операнд2 и ако не е, прави преход. Аз защо казвам, че 8051 е класика, а?

Например: CJNE R1, #5, loop_proc


Пет Фев 10, 2006 10:37 am
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Вто Окт 25, 2005 10:54 am
Мнения: 896
Мнение 
bateAz написа:
В i8051 има CJNE - с една инструкция: проверява дали операнд1 = операнд2 и ако не е, прави преход. Аз защо казвам, че 8051 е класика, а?

Например: CJNE R1, #5, loop_proc


малко офтопик: присъединявам се към батето с аргумента че поне на мен това е единствения ми познат ЦПУ който може да прави "mov [addr], [addr]" с една инструкция :)


Пет Фев 10, 2006 12:31 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Фев 10, 2006 2:10 am
Мнения: 19
Местоположение: Sofia
Мнение 
Само не разбрах памет ли се пести или скорост
ако е скорост и стойностите са само 0-5 можеш да скочиш по таблица с индекс брояча ти
в някои процесори има много бързи команди за такива преходи


Пет Фев 10, 2006 1:10 pm
Профил ICQ WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 17 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни