Когда происходит переполнение счетчика

Содержание
  1. Когда происходит переполнение счетчика
  2. Re: Алгоритм регистрации переполнений
  3. Re: Алгоритм регистрации переполнений
  4. Re: Алгоритм регистрации переполнений
  5. Re: Алгоритм регистрации переполнений
  6. Re: Алгоритм регистрации переполнений
  7. Re: Алгоритм регистрации переполнений
  8. Re: Алгоритм регистрации переполнений
  9. Re: Алгоритм регистрации переполнений
  10. Re: Алгоритм регистрации переполнений
  11. Re: Алгоритм регистрации переполнений
  12. Re: Алгоритм регистрации переполнений
  13. Re: Алгоритм регистрации переполнений
  14. Re: Алгоритм регистрации переполнений
  15. Re: Алгоритм регистрации переполнений
  16. Re: Алгоритм регистрации переполнений
  17. Re: Алгоритм регистрации переполнений
  18. Re: Алгоритм регистрации переполнений
  19. Re: Алгоритм регистрации переполнений
  20. Re: Алгоритм регистрации переполнений
  21. Re: Алгоритм регистрации переполнений
  22. Re: Алгоритм регистрации переполнений
  23. Re: Алгоритм регистрации переполнений
  24. Re: Алгоритм регистрации переполнений
  25. Re: Алгоритм регистрации переполнений
  26. Re: Алгоритм регистрации переполнений
  27. Re: Алгоритм регистрации переполнений
  28. Re: Алгоритм регистрации переполнений
  29. Когда происходит переполнение счетчика
  30. Кто сейчас на форуме

Когда происходит переполнение счетчика

alibek » 30.05.2011 (Пн) 8:12

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

Есть устройство, с которого по SNMP собирается информация.
Один из датчиков — счетчик трафика на интерфейсе. Тип данных — COUNTER (32-битный).
У этого типа данных есть такая особенность — когда он переполняется, он обнуляется.
Эти данные отображаются на графике, причем отображается не значение счетчика, а его производная (т.е. рисуется график загрузки канала); причем программа, рисующая график, знает об особенностях переполнения счетчиков, поэтому когда текущее значение счетчика получается меньше предыдущего, значит произошло переполнение и изменение (разница между текущим и предыдущим значением счетчика) определяется с учетом переполнения.
Программа, рисующая график, получает данные не напрямую по SNMP, а от cgi-скриптов, которые получают данные и передают их в программу.

Нужно модифицировать скрипт таким образом, чтобы он суммировал счетчики на нескольких (например двух) интерфейсах.
И тут возникают сложности с тем, как определять и обрабатывать переполнения.
Сам скрипт, опрашивающий данные, информации о динамике счетчика и его предыдущих значениях не имеет (их в принципе можно получить, но это усложнит скрипт и значительно снизит его производительность).

Re: Алгоритм регистрации переполнений

Хакер » 31.05.2011 (Вт) 16:14

Re: Алгоритм регистрации переполнений

alibek » 31.05.2011 (Вт) 16:54

Re: Алгоритм регистрации переполнений

Хакер » 31.05.2011 (Вт) 17:04

  1. Зачем его фиксировать? При вычислении производной оно автоматически уходит в силу особенностей организации беззнаковой арифметики.
  2. Посмотрим подругому: почему с одним счётчиком проблемы нет, а со многими она возникает. В каком месте при переходе от одного счётчика к нескольким возникает проблема?

Re: Алгоритм регистрации переполнений

Proxy » 31.05.2011 (Вт) 21:13

Re: Алгоритм регистрации переполнений

Хакер » 31.05.2011 (Вт) 21:25

Это антисовет. Суммирование значение счётчиков само при себе может привести к переполнению. Суммирование значений 4 счётчиков может дать 3 переполнения, а может дать и одна. И нельзя точно сказать, сколько их произошло.

Нужно для каждого счётчика вычислить дельту. А потом сложить вместе дельты. При этом вычисление дельты никак не нарушается от влияния переполнения.

Допустим, счётчик был бы не 32-, а 8-битным. Пусть предпоследнее измерение дало 250, а текущее 5. Если отнять от пятерчки число 250, то результат будет 11.

Re: Алгоритм регистрации переполнений

Proxy » 01.06.2011 (Ср) 7:01

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 12:30

Re: Алгоритм регистрации переполнений

Proxy » 01.06.2011 (Ср) 12:55

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 12:57

Дельту считает программа, получающая значения счётчиков от cgi-скрипта, получающего их по SNMP?

Если так, так для нескольких счётчиков скрипт должен отдавать несколько значений, программа должна вычислять дельту отдельно для каждого из счётчиков, а потом суммировать дельты.

Читайте также:  Неисправность электросчетчика меркурий 206

Алибек, почему ты молчишь?

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 13:47

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 13:49

Она чужая и с закрытым исходным кодом?

А в какой разрядности получает данные программа? Или она получает их в текстовом виде?

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 14:18

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 14:19

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 14:26

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 14:29

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 14:52

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 15:05

Почему он не может сохранять где-то предыдущие значения и время предыдущего измерения?

Хотя, кстати, давай так. Предположим, что счётчики у нас не 32-битные, а 8-битные. Просто, чтобы не нагружать самих себя длинными числами (4 миллиарда . ). Счётчик 8-битный и переполнение наступает после значения 255.

Приведи пример в следующей форме:
Код: Выделить всё Было: Прибавилось: Стало:
C1A C1D C1B
C2A C2D C2B
C3A C3D C3B
. . .
CnA CnD CnB
—————————-
Сумма: Total_A Total_D Total_B

при котором переполнение что-то бы портило .

Я пришёл к выводу , что переполнение страшно только в следующем случае: если сумма приростов значений счётчиков между двумя ближайшими измерениями больше чем 2 в степени, равной разрядности счётчика. То есть между двумя ближайшими измерениями через все интерфейсы успеют прокачать 4 Гб трафика, тогда да, переполнения страшны.

Вот пример с 8-битными счётчиками. Числа в десятичной системе счисления.
Код: Выделить всё Арифметика с переполнениями (computer-like):

Было: Прибавилось: Стало:
255 000 255
255 001 000
255 002 001
255 003 002
010 004 014
—————————-
Сумма: 006 010 016

Код: Выделить всё Арифметика без переполнений (human-like):

Было: Прибавилось: Стало:
255 000 255
255 001 256
255 002 257
255 003 258
010 004 014
—————————-
Сумма: 1030 010 1040

Как видишь, то, что переполнение происходит, никак не искажает результаты . Производная (то есть дельта) вычисляется правильно: несмотря на то, что при суммировании счётчики многократно переполнялись, дельта и там и там даёт 10.

C 32-битными счётчикам будет всё точно так же.

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 15:30

Это нереально.
Во-первых, производится опрос нескольких десятков устройств, в каждом из которых нужно суммировать несколько групп интерфейсов, т.е. нужно сохранять несколько сотен промежуточных значений.
Во-вторых, алгоритм определения переполнений несколько сложнее, т.к. он должен учитывать возможные сбои (не отработал SNMP-запрос, возвратилось неправильное значение), т.е. отбрасывать значения, сильно выбивающиеся из статистики.

По поводу того, что переполнения не меняют картины.
Допустим, счетчики 8-разрядные.
Измерение 1: 0 0 0 0 (сумма 0)
Измерение 2: 10 1 80 20 (сумма 111, дельта 10+1+80+20=111)
Измерение 3: 30 10 200 50 (сумма 290 или 35, дельта 20+9+120+30=179)
Измерение 4: 80 20 30 100 (сумма 230, дельта 50+10+85+50=195)

Вообщем-то да, если эмулировать переполнение суммарного значения, то дельта не меняется.
Если его не эмулировать, тогда внешняя программа неправильно определяет разрядность счетчика (раз пришло 290, значит разрядность выше 8 бит) и поэтому неправильно считает дельту.

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 15:35

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 15:43

Сумм тоже много (пара сотен).

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 15:56

Ну и? 800 байтов, это смертельно?

Я всё-таки не могу понять саму суть проблемы. Вот GetTickCount() возвращает беззнаковый 32-битный результат, он тоже переполняется, но никого это не волнует, потому значение счётчика после переполнения минус значение счётчика до переполнения даст правильный временной интервал-результат. Неправильный результат будет только в том случае, если между двумя ближайшими измерениями счётчик тиков переполнялся более 1 раза.

Читайте также:  Телеметрический выход счетчика как подключить

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 16:03

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 16:05

Эмулировать? Речь идёт о специфике скриптового языка, в котором переполнение не происходит само собой естественным образом?

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 16:54

А каков естественный образ?
В скриптовых языках при переполнении происходит ошибка.

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 17:00

Естественный образ таков, что когда процессор считает 0xFFFFFFFF + 2, то (естественным образом) получается 0x0000001. А когда отнимаем от числа 5 число 0xFFFFFFFF, получаем 6. То есть, если писать на Си/С++, то:
Код: Выделить всё old_time = GetTickCount(); // За 1 секунду до переполнения, вернёт 4294966296
. что-то делаем .
new_time = GetTickCount(); // Через 2 секунду после переполнения, вернёт 2000

printf(«%d\n», new_time — old_time); // Выведет 3000 без всяких контролей переполнения
Причём даже не важно, какие типы (signed или unsigned) мы используем, результат будет одинаков из-за того, что процессор и signed и unsigned числа считает одним и тем же образом, даже не беря во внимание разницу). Единственная вещь, где разница между типами signed и unsigned доходит до процессора — это инструкции сравнения.

Re: Алгоритм регистрации переполнений

alibek » 01.06.2011 (Ср) 17:13

Re: Алгоритм регистрации переполнений

Хакер » 01.06.2011 (Ср) 17:18

Ну, в VB похожая ситуация, и чтобы добиться поведения как в Си, я сделал следующие функции (вообще, они в составе несколько более полного модуля, может быть и стоит его опубликовать):
Код: Выделить всё Private Const BITMSK_NEGATIVE_BIT_DW As Long = &H80000000
Private Const BITMSK_NEGATIVE_BIT_W As Integer = &H8000
Private Const BITMSK_NEGATIVE_BIT_B As Byte = &H80

Private Const BITMSK_ALL_BITS_DW As Long = &HFFFFFFFF
Private Const BITMSk_ALL_BITS_W As Integer = &HFFFF
Private Const BITMSK_ALL_BITS_B As Byte = &HFF

Public Function EmAddUnsigned(ByVal ul1 As Long, ByVal ul2 As Long) As Long
If (BITMSK_NEGATIVE_BIT_DW And ul1) = _
(BITMSK_NEGATIVE_BIT_DW And ul2) Then

‘ Либо два неотрицательных числа, либо два отрицательных. Их
‘ сложение может дать переполнение, поэтому сделаем из них
‘ два разнознаковых числа (такие никогда не дадут переполнение):
‘ инвертируем одному из них MSB, складываем, а потом инвертируем
‘ MSB у результата. Биты инвертируются оператором Xor.

Const MSB As Long = BITMSK_NEGATIVE_BIT_DW ‘ Самый старший бит
EmAddUnsigned = ((ul1 Xor MSB) + ul2) Xor MSB
Else

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

EmAddUnsigned = ul1 + ul2
End If
End Function

Public Function EmSubtractUnsigned(ByVal ul1 As Long, _
ByVal ul2 As Long) As Long

‘ Заранее предостерегаю от идеи сделать эту функцию как обёртку над
‘ EmAddUnsigned(ul1, -ul2). Выражение (-ul2) может дать overflow.
‘ Эта функция использует тот же принцип, что и EmAddUnsigned, но
‘ с обратной логикой выбора способа.

If (BITMSK_NEGATIVE_BIT_DW And ul1) = _
(BITMSK_NEGATIVE_BIT_DW And ul2) Then
EmSubtractUnsigned = ul1 — ul2
Else

Const MSB As Long = BITMSK_NEGATIVE_BIT_DW ‘ Самый старший бит
EmSubtractUnsigned = ((ul1 Xor MSB) — ul2) Xor MSB
End If
End Function

Источник

Когда происходит переполнение счетчика

.device atmega8a
.nolist
.include «D:\prg\AVRStudio419\AvrAssembler2\Appnotes\m8Adef.inc»
.list
;=======Прерывание компаратора (переполнение счетчика) Вариант2

.def temp=r16
.def temp1=r17

rjmp RESET ;Переход на обработку сброса
rjmp EXT_INT0 ;Переход на обработку запроса IRQ0
rjmp EXT_INT1 ;Переход на обработку запроса IRQ1
rjmp TIM2_COMP ;Переход на обработку сравнения Timer2
rjmp TIM2_OVF ;Переход на обработку при переполнении Timer2
rjmp TIM1_CAPT ;Переход на обработку при захвате фронта Timer1
rjmp TIM1_COMPA ;Переход на обработку при срабатывании компаратора A Timer1
rjmp TIM1_COMPB ;Переход на обработку при срабатывании компаратора B Timer1
rjmp TIM1_OVF ;Переход на обработку при переполнении Timer1
rjmp TIM0_OVF ;Переход на обработку при переполнении Timer0
rjmp SPI_STC ;Переход на обработку при завершении передачи SPI
rjmp USART_RXC ;Переход на обработку при завершении приема УСАПП0
rjmp USART_UDRE ;Переход на обработку при освобождении регистра
rjmp USART_TXC ;Переход на обработку при завершении передачи
rjmp ADC_END ;Переход на обработку при завершении преобразования AЦП
rjmp EE_RDY ;Переход на обработку при готовности EEPROM
rjmp ANA_COMP ;Переход на обработку при срабатывании аналогового компаратора
rjmp TWSI ;Двухпроводный Последовательный интерфейс
rjmp SPM_RDY ;Переход на обработку прерывания при Готовности записи в память программ

Читайте также:  Установку газовых счетчиков отложили

RESET:
rjmp Init

Init:
ser temp ;в результате temp=0xFF
out DDRB,temp ;весь регистр B ориентировали на выход
out DDRD,temp ;весь регистр D ориентировали на выход

ldi temp,Low(RamEnd) ;в temp посл. адрес ОЗУ (младший байт)
out SPL,temp ;задать младший байт указателя стека
ldi temp,High(RamEnd) ;в temp посл. адрес ОЗУ (старший байт)
out SPH,temp ;задать старший байт указателя стека

ldi temp,0b00000001
out PortB,temp ;включить красный СИД1
ldi temp,0b00000000
out PortD,temp ;включить зеленый (инверсный) СИД1

ldi temp,0b00010001
out TIMSK,temp ;разрешить прерывание компаратора (в т.ч. по переполнению)

ldi Temp,0b00000010 ;тактовый сигнал = CK/8
out TCCR1B,Temp

ldi Temp,0x4C ;инициализация компаратора
out OCR1AH,Temp
ldi Temp,0x4B
out OCR1AL,Temp

ldi Temp1,0b00000001 ;инициализация индикатора

sei ;разрешить прерывания

ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp

Inf: rjmp Inf ;бесконечный цикл

TIM1_COMPA:
rol Temp1 ;сдвиг влево
out PortB,Temp1 ;вывод в порт
reti ;выход из обработчика

TIM1_OVF:
TIM0_OVF:
ldi temp,0b00000001
out PortD,temp ;выключить зеленый (инверсный) СИД1
ret ;выход из обработчика с последующим запретом прерываний

Реклама
Z_h_e
Собутыльник Кота

Карма: 25
Рейтинг сообщений: 641
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2637
Откуда: г. Чайковский
Рейтинг сообщения: 2
Медали: 1

_________________

Добро всегда побеждает зло. Поэтому кто победил — тот и добрый.

Реклама

JLCPCB, всего $2 за прототип печатной платы! Цвет — любой!

Зарегистрируйтесь и получите два купона по 5$ каждый:https://jlcpcb.com/quote

akl
Друг Кота

Карма: 59
Рейтинг сообщений: 843
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 3846
Откуда: Ижевск
Рейтинг сообщения: 0

Реклама

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

z11
Родился

Зарегистрирован: Вс июн 21, 2015 10:07:14
Сообщений: 6
Рейтинг сообщения: 0

а это, аналогичный пример, но на основе прерывания по переполнению 8-разрядного счетчика 0.

Оба примера для МК ATMega8A-PU с собственным источником тактового сигнала (1 Мегагерц). СИДы подключены к выводам регистра PB. Кстати, интересный момент: обнаружил различие между даташитами для ATMega8 и для ATMega8A в описании регистра TCCR0. В виду того, что в рунете нет на русском даташита для ATMega8A, это плохая новость.

Реклама

Помимо стабильности основных технических характеристик карбид-кремниевых транзисторов линейки CoolSiC, компания Infineon довела до значений, соответствующих кремниевым аналогам, такие параметры, как устойчивость к временной деградации кристаллов и воздействию космического излучения. В процессе исследований были применены уникальные комплексные тесты, который могут в ближайшем будущем стать промышленным стандартом для испытаний SiC-приборов.

Страница 1 из 1 [ Сообщений: 4 ]

Часовой пояс: UTC + 3 часа

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

Источник

Поделиться с друзьями
Блог электрика
Adblock
detector