Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » FAQ по Bascom AVR и МК » Скорость работы операторов Bascom


Скорость работы операторов Bascom

Сообщений 1 страница 28 из 28

1

Возможно, кому-то эта информация будет полезна...
Я - не первый в подобных сравнениях, но, тем не менее... ;)

Проверялось в Симуляторе Bascom при 1МГц МК.
Временные характеристики следует пересчитывать с учетом физической тактовой частоты.

Отредактировано Nord (2019-07-28 19:34:34)

0

2

‘******************************************************************
Присвоение значений
‘==================================================================
Для  А = BYTE
А = 1
Время выполнения – 4 такта
‘ ----------------------------------
Для  А = INTEGER
А = 1
Время выполнения – 9 тактов
‘==================================================================

‘******************************************************************
Операция сложения
‘==================================================================
Для  А = BYTE, B = BYTE
А = А + 1
Время выполнения – 8 тактов
А = А + B
Время выполнения – 10 тактов
‘ ----------------------------------
Для  А = INTEGER , B = INTEGER
А = A + 1
Время выполнения – 15 тактов
А = А + B
Время выполнения – 20 тактов
‘==================================================================

‘******************************************************************
Выполнение циклов
‘==================================================================
Для  А = BYTE
‘ ----------------------------------
For A = 1 To 1
Next A
Одинарный пустой цикл (без внутренних операций) выполняется за 27 тактов.
Здесь «работают» только операции начала и завершения цикла.
‘ ----------------------------------
For A = 1 To 2
Next A
Цикл с повтором более 1 выполняется за 27 + 15 тактов.
15 тактов – каждый последующий повтор.

Для A = 1 To 10 будет 162 такта - 27 + 9 * 15 тактов
‘==================================================================
Для  А = INTEGER
‘ ----------------------------------
For A = 1 To 1
Next A
Одинарный пустой цикл (без внутренних операций) выполняется за 55 тактов.
‘ ----------------------------------
For A = 1 To 2
Next A
Цикл с повтором более 1 выполняется за 55 + 32 тактов.
32 такта – каждый последующий повтор.

Для A = 1 To 10 будет 343 такта - 55 + 9 * 32 такта
‘==================================================================

‘******************************************************************
Вызов подпрограммы
‘==================================================================
Пустой Gosub …. Return, без какого-либо выполнения внутри подпрограммы.
8 тактов.
‘ ----------------------------------

Gosub …. Return с операцией присвоения внутри подпрограммы
‘ ----------------------------------
Для  А = BYTE
‘ ----------------------------------
Gosub … A = n ... Return
11 тактов
‘ ----------------------------------
Для  А = INTEGER
‘ ----------------------------------
15 тактов

Gosub …. Return с арифметической операцией внутри подпрограммы
‘ ----------------------------------
Для  А = BYTE
‘ ----------------------------------
Gosub … A = A + B ... Return
15 тактов
‘ ----------------------------------
Для  А = INTEGER
‘ ----------------------------------
22 такта
‘==================================================================

Отредактировано Nord (2019-07-26 08:32:59)

+4

3

‘******************************************************************
Арифметические операции
‘==================================================
А = A * n
‘ ----------------------------------
Для  А = BYTE          ‘ Время выполнения – 10 тактов
Для  А = INTEGER    ‘ Время выполнения – 36 тактов
Для  А = SINGLE      ‘ Время выполнения – 280 тактов
‘ ----------------------------------
А = A * B
‘ ----------------------------------
Для  А и B = BYTE          ‘ Время выполнения – 11 тактов
Для  А и B = INTEGER    ‘ Время выполнения – 40 тактов
Для  А и B = SINGLE      ‘ Время выполнения – 232 такта
‘==================================================

‘******************************************************************
А = A \ n
‘ ----------------------------------
Для  А = BYTE          ‘ Время выполнения – 68 тактов
Для  А = INTEGER    ‘ Время выполнения – 290 тактов
Для  А = SINGLE      ‘ Время выполнения – 572 такта
‘ ----------------------------------
А = A \ B
‘ ----------------------------------
Для  А и B = BYTE          ‘ Время выполнения – 113 тактов
Для  А и B = INTEGER    ‘ Время выполнения – 294 тактов
Для  А и B = SINGLE      ‘ Время выполнения – 524 такта
‘===================================================

+3

4

n какой тип?

0

5

EdGull написал(а):

n какой тип?

Судя по всему это просто число, т. е. А = A * 100.

Нужно еще проверить с Long.

0

6

EdGull написал(а):

n какой тип?

Во всех случаях значение n было одинаковым = 5.

Поэтому указанные скорости не являются однозначно единственными.
Но даже указанных значений вполне хватает для представления картины действа... ;)

0

7

Для LONG
‘******************************************************************
А = A * n                  ' n = 5
‘ ----------------------------------
Для  А = LONG                ‘ Время выполнения – 98 тактов
----------------------------------
А = A * B
‘ ----------------------------------
Для  А и B = LONG          ‘ Время выполнения – 88 тактов
' ----------------------------------
А = A \ n                  ' n = 5
‘ ----------------------------------
Для А = LONG                 ‘ Время выполнения – 768 тактов
‘ ----------------------------------
А = A \ B
‘ ----------------------------------
Для  А и B = LONG          ‘ Время выполнения – 792 такта
===================================================

+2

8

‘******************************************************************
Операции с чтением DATA
‘==================================================================
Restore xxx               ‘ Время выполнения – 12 тактов
Только формирование указателя, без каких-либо других действий.
‘ ----------------------------------
Read A                      ‘ A = String * 4
Для  А = “A”              ‘ Время выполнения – 1647 тактов
Для значений в блоке DATA от «А» до «АААА» скорость не изменяется.
Для более длинных строк эксперименты не проводились.
‘ ----------------------------------
Read A                     ‘ Одиночное считывание, значение в блоке DATA во всех случаях = 110
Для  А = BYTE          ‘ Время выполнения – 36 тактов
Для  А = INTEGER    ‘ Время выполнения – 66 тактов
Для  А = SINGLE      ‘ Время выполнения – 102 такта
Для  А = LONG         ‘ Время выполнения – 102 такта
‘ ----------------------------------
Чтение из блока DATA в цикле
Значение в блоке DATA во всех случаях = 110
Для  А = BYTE
For B = 1 To 1           ‘ Время выполнения – 62 тактa
For B = 1 To 2           ‘ Время выполнения – 62 + 50 тактов
For B = 1 To n           ‘Каждое значение цикла более 2 добавляет 50 тактов

Для  А = INTEGER
For B = 1 To 1           ‘ Время выполнения – 92 такта
For B = 1 To 2           ‘ Время выполнения – 92 + 80 тактов
For B = 1 To n           ‘ Каждое значение цикла более 2 добавляет 80 тактов

Для  А = SINGLE
For B = 1 To 1           ‘ Время выполнения – 128 тактов
For B = 1 To 2           ‘ Время выполнения – 128 + 116 тактов
For B = 1 To n           ‘ Каждое значение цикла более 2 добавляет 116 тактов

Для  А = LONG
For B = 1 To 1           ‘ Время выполнения – 128 тактов
For B = 1 To 2           ‘ Время выполнения – 128 + 116 тактов
For B = 1 To n           ‘ Каждое значение цикла более 2 добавляет 116 тактов

‘==================================================================

Отредактировано Nord (2019-07-30 18:42:53)

+3

9

‘******************************************************************
Операции преобразования «Num» <> «Txt»
‘==================================================================
Dim S As String * 16
A = 5
S = HEX(A)
‘ ----------------------------------
Для  А = BYTE           ‘ Время выполнения – 58 тактов
Для  А = INTEGER     ‘ Время выполнения – 94 такта
Для  А = SINGLE       ‘ Время выполнения – 164 такта
Для  А = LONG          ‘ Время выполнения – 164 такта

S = BIN(A)
‘ ----------------------------------
Для  А = BYTE           ‘ Время выполнения – 91 такт
Для  А = INTEGER     ‘ Время выполнения – 160 тактов
Для  А = SINGLE       ‘ Время выполнения – 296 тактов
Для  А = LONG          ‘ Время выполнения – 296 тактов

Dim S As String * 4
S = “100”
A = VAL(S)
‘ ----------------------------------
Для  А = BYTE           ‘ Время выполнения – 291 такт
Для  А = INTEGER     ‘ Время выполнения – 293 такта
Для  А = SINGLE       ‘ Время выполнения – 457 тактов
Для  А = LONG          ‘ Время выполнения – 297 тактов

‘==================================================================
Афигеть скорости...  o.O
Надо завязывать с текстовыми переменными... ;)

+2

10

‘******************************************************************
Операции с переменными типа STRING
‘===================================================
Dim S As String * 1
Dim K As String * 4
‘ ----------------------------------
K = K + S                 ‘ Время выполнения – 42 такта
‘ ----------------------------------
Dim S As String * 2
K = K + S                 ‘ Время выполнения – 49 тактов
‘ ----------------------------------
Dim S As String * 3
K = K + S                 ‘ Время выполнения – 56 тактов
….
Эксперимент проводился до S = 30 символов, прирост не изменяется.
На каждый символ используется  +7 тактов программного времени.

Dim S As String * 4
Dim K As String * 6
K = “BASCOM”
‘ ----------------------------------
S = Mid(K, 1, 1)        ‘Время выполнения – 44 такта
S = Mid(K, 1, 2)        ‘Время выполнения – 54 такта
S = Mid(K, 1, 3)        ‘Время выполнения – 64 такта
Эксперимент проводился до Mid(K, 1, 30), прирост не изменяется.
На каждый символ используется  +10 тактов программного времени.

Dim S As String * 4
Dim K As String * 6
K = “xB”                   ‘ х – некоторое количество «пробелов», Chr(32), в начале строки
‘ ----------------------------------
S = Ltrim(K)             ‘Время выполнения – 34 такта для 1 «пробела»
S = Ltrim(K)             ‘Время выполнения – 39 тактов для 2 «пробелов»
На каждый «пробел» более одного добавляется  5 тактов
Например, для строки «_____В» будет выполнено 34 + (5 * 5) тактов

K = “Bх”                   ‘ х – некоторое количество «пробелов», Chr(32), в конце строки
‘ ----------------------------------
S = Rtrim(K)             ‘Время выполнения – 57 тактов для 1 «пробела»
S = Rtrim(K)             ‘Время выполнения – 69 тактов для 2 «пробелов»
На каждый «пробел» более одного добавляется  12 тактов
Например, для строки «В_____» будет выполнено 57 + (5 * 12) тактов

K = “хBх”                  ‘ х – некоторое количество «пробелов», Chr(32), в начале и (или) в конце строки
‘ ----------------------------------
K = “Bх”
S = Trim(K)               ‘Время выполнения – 63 такта
K = “Bхх”
S = Trim(K)               ‘Время выполнения – 75 тактов
На каждый «пробел» более одного добавляется  12 тактов
Например, для строки «В_____» будет выполнено  63 + (5 * 12) тактов
‘ ----------------------------------
K = “хB”
S = Trim(K)               ‘Время выполнения – 56 тактов
K = “ххB”
S = Trim(K)               ‘Время выполнения – 61 такт
На каждый «пробел» более одного добавляется  5 тактов
Например, для строки «_____В» будет выполнено  56 + (5 * 5) тактов
‘ ----------------------------------
K = “хBх”
S = Trim(K)               ‘Время выполнения – 68 тактов
K = “ххBх”
S = Trim(K)               ‘Время выполнения – 73 такта
На каждый «пробел» перед значимыми данными более одного добавляется  5 тактов
K = “хBхх”
S = Trim(K)               ‘Время выполнения – 80 тактов
На каждый «пробел» после значимых данных более одного добавляется  12 тактов

‘===================================================

Отредактировано Nord (2019-08-03 23:18:47)

+1

11

‘******************************************************************
Вызов подпрограмм (в дополнение к #2)
‘====================================================
Declare Sub Probe
Call Probe
Пустой Call, без какого-либо выполнения внутри подпрограммы - 8 тактов.
‘ ----------------------------------
Declare Sub Probe(byval A As Byte)
Call Probe(A)            ‘ Здесь и далее в подпрограмме выполняется А = 5
Время выполнения – 48 тактов
‘ ----------------------------------
Declare Sub Probe(byval A As Integer)
Call Probe(A)
Время выполнения – 57 тактов
‘ ----------------------------------
Declare Sub Probe(byval A As Single)
Call Probe(A)
Время выполнения – 161 такт
‘ ----------------------------------
Declare Sub Probe(byval A As Long)
Call Probe(A)
Время выполнения – 71 такт      :confused:
‘ ----------------------------------

Ощутимо медленнее, чем Gosub …. Return… ;)
‘====================================================

Отредактировано Nord (2019-08-04 23:18:46)

+2

12

Nord написал(а):

Ощутимо медленнее, чем Gosub …. Return

Подпрограммы не поддерживают аргументы и локальные переменные.

0

13

‘******************************************************************
Форматирование строковых переменных
‘==================================================================
Dim K As String * 6
Dim A As Single
A = 55.256
‘ ----------------------------------
K = Fusing(A, "#.#")
Время выполнения – 6256 тактов
‘ ----------------------------------
K = Fusing(A, "#.##")
Время выполнения – 6279 тактов
‘ ----------------------------------
K = Fusing(A, "#.###")
Время выполнения – 6215 тактов
‘ ----------------------------------
K = Fusing(A, "#.&")
Время выполнения – 6194 такта
‘ ----------------------------------
K = Fusing(A, "#.&&")
Время выполнения – 6201 такт
‘ ----------------------------------
K = Fusing(A, "#.&&&")
Время выполнения – 6208 тактов
‘==================================================================

+2

14

‘******************************************************************
Операции сравнения
‘==================================================
Dim A As BYTE
Dim B As BYTE
A = 5
B = 5

If B < A Then Gosub probe    ‘ Здесь и далее использован «пустой» Gosub … Return
‘ Время выполнения – 9 тактов, здесь и далее время выполнения «пустого» Gosub убрано
If B > A Then Gosub probe
‘ Время выполнения – 11 тактов
If B = A Then Gosub probe
‘ Время выполнения – 3 такта

If A < 5 Then Gosub probe
‘ Время выполнения – 7 тактов
If A > 5 Then Gosub probe
‘ Время выполнения – 9 тактов
If A = 5 Then Gosub probe
‘ Время выполнения – 5 тактов
‘ ----------------------------------
Dim A As INTEGER
Dim B As INTEGER
A = 5
B = 5

If B < A Then Gosub probe
‘ Время выполнения – 19 тактов
If B > A Then Gosub probe
‘ Время выполнения – 20 тактов
If B = A Then Gosub probe
‘ Время выполнения – 9 тактов

If A < 5 Then Gosub probe
‘ Время выполнения – 14 тактов
If A > 5 Then Gosub probe
‘ Время выполнения – 15 тактов
If A = 5 Then Gosub probe
‘ Время выполнения – 4 такта
‘ ----------------------------------

Отредактировано Nord (2019-08-14 00:24:57)

+2

15

А FORMAT есть возможность проверить?

0

16

Dim S As String * 6
S = "12345"

S = Format(s , "+")                  ' 181 такт
S = Format(s , "00000")           ' 180 тактов

S = Format(s , "000.00")          ' 207 тактов
S = Format(s , "+000.00")        ' 209 тактов

S = Format(s , "00.000")          ' 214 тактов
S = Format(s , "+00.000")        ' 216 тактов

Это навскидку...
Какой вариант интересует в конечном виде ?

+2

17

Спасибо , так сойдет, для общего развития.

0

18

Интересное наблюдение... ;)

Команды:

PORTA.0 = 0
PORTA.0 = 1

Set PORTA.0
Reset PORTA.0

Toggle PORTA.0

- все отрабатывают одинаково - 3 такта.
Ожидалась разница... ;)

0

19

это одна и та же команда на асме, пофигу как на верхнем уровне

ps
а вот почему Toggle так оттранслировалась - вопрос... не глядел я асм Баскома для каждой команды.

Отредактировано Александр Д. (2019-08-21 11:30:00)

0

20

В дополнение к #16...

Dim S As String * 1

S = "1"

S = Format(s , "+")                   ' 93 такта

На каждый дополнительный символ в форматируемой строке + 22 такта.
Другие варианты, рассмотренные в #16, не проверял, но тенденция уже видна.

0

21

‘******************************************************************
Операции округления и т.п.
‘==================================================

A = 0.5
‘ ----------------------------------
B = Abs(A)
для:
Integer - 26 тактов
Single - 65 тактов
Long - 38 тактов
Double - 55 тактов

B = Fix(A)
для:
Single - 118 тактов
Double - 154 такта

B = Round(A)
для:
Single - 268 тактов
Double - 794 такта

B = Int(A)
для:
Single - 117 тактов
Double - 159 тактов

B = Frac(A)
для:
Single - 101 такт

Отредактировано Nord (2019-08-24 23:12:19)

+4

22

На официальном форуме человек выложил функцию, которая на ЖКИ выводит количество тактов между её вызовами. Я думаю, что несложно переделать и на УАРТ.

Примеры:

Код:
MCUcycle 16000000                                        ' The LCD should shown a 3. For 3 clock cycles of the MCU between these two Statements
ByteA = 1 + 2
MCUcycle 16000000


Код:
MCUcycle 16000000                                        ' The LCD should shown a 10. For 10 clock cycles of the MCU between these two Statements
ByteA = 1 + 2
ByteA = ByteA + 7
MCUcycle 16000000


Код:
MCUcycle 16000000                                       ' The LCD should shown a 13. For 13 clock cycles of the MCU between these two Statements
ByteA = 1 + 2
ByteA = ByteA + 7
ByteB = 1 + 2
MCUcycle 16000000


Сама функция:

Код:
Sub Mcucycle(byval Mcuspeed As Dword)
   Local Mcucount As Dword

   If Byteengage = 0 Then
      Start Timer1
      Byteengage = 255
   Else
      Stop Timer1
      Mcucount = Timer1
      Mcucount = Mcucount - 89
      Cls
      Locate 1 , 1
      Lcd Mcucount
      Timer1 = Timer1preload
      Byteengage = 0
   End If

End Sub


И весь код:

Код:
 ' Specific MCU Clock Cycle Counter
 ' By Michael B.


$regfile = "m32def.DAT"
$crystal = 16000000
$hwstack = 30
$swstack = 30
$framesize = 40
$timeout = 20

Defbyte Byte

Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 4

Declare Sub Mcucycle(byval Mcuspeed As Dword)

Config Timer1 = Timer , Prescale = 1
Stop Timer1
Const Timer1preload = 0
Timer1 = Timer1preload
Enable Interrupts


Do


   Mcucycle 16000000                                        ' The LCD should shown a 10. For 10 clock cycles of the MCU between these two Statements
   Bytea = 1 + 2
   Bytea = Bytea + 7
   Mcucycle 16000000

   Wait 3
   Mcucycle 16000000                                        ' The LCD should shown a 20. For 20 clock cycles of the MCU between these two Statements
   Bytea = 1 + 2
   Bytea = Bytea + 7
   Byteb = 1 + 2
   Byteb = Byteb + 7
   Mcucycle 16000000

   Wait 3
   Mcucycle 16000000                                        ' The LCD should shown a 30. For 30 clock cycles of the MCU between these two Statements
   Bytea = 1 + 2
   Bytea = Bytea + 7
   Byteb = 1 + 2
   Byteb = Byteb + 7
   Bytec = 1 + 2
   Bytec = Bytec + 7
   Mcucycle 16000000

   Wait 3
   Mcucycle 16000000                                        ' The LCD should shown a 3. For 3 clock cycles of the MCU between these two Statements
   Bytea = 1 + 2
   Mcucycle 16000000

Loop

End

Sub Mcucycle(byval Mcuspeed As Dword)
   Local Mcucount As Dword

   If Byteengage = 0 Then
      Start Timer1
      Byteengage = 255
   Else
      Stop Timer1
      Mcucount = Timer1
      Mcucount = Mcucount - 89
      Cls
      Locate 1 , 1
      Lcd Mcucount
      Timer1 = Timer1preload
      Byteengage = 0
   End If

End Sub

0

23

Нечто подобное я делал в "ms", для оценки производительности обычным человеком. :)

Что касаемо кода, посчитать 1 такт таймером сложно даже с прескейлером в 1, т.к. на запуск и остановку надо доп. количество тактов, далее начинается вычисления с этим учетом (т.е. синтетика).

Кстати говоря, можно поиграться с идеей запоминания программного счетчика через стек.

Отредактировано RDW (2019-10-01 11:09:53)

+1

24

RDW написал(а):

Нечто подобное я делал в "ms", для оценки производительности обычным человеко

А поделится можете?

0

25

radan написал(а):

А поделится можете?

Думаю - да, но не сейчас, дома кап ремонт, как время покоя найдётся...вся техника отключена.

Отредактировано RDW (2019-10-01 11:10:27)

0

26

RDW написал(а):

Что касаемо кода, посчитать 1 такт таймером сложно даже с прескейлером в 1, т.к. на запуск и остановку надо доп. количество тактов, далее начинается вычисления с этим учетом (т.е. синтетика)

Именно по этому я и отказался от предложенного способа силами Протеуса и пользуюсь эмулятором Bascom.
Таймер - понятие растяжимое... ;)

0

27

radan написал(а):

А поделится можете?

Код/идея весьма простая и да, она тоже на таймере (без чудес).

Инициализация:

Код:
$crystal = 8000000                                          '8000000 / 18432000

' 8000000 / 256 = 31250
' 31250 = 1000 ms
' 31.250 = 1 ms
Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1
Stop Timer1

Dim Tms_en As Byte                                          ' <-= включалка измерения времени (Tms_en=1)
Dim Tms As Single
Dim Tms_word As Word


Далее само измерение, можно проверить на баскомовском операторе "waitms":

Код:
Enable Interrupts

Do
   Gosub Time_start             ' <-==== измерение производительности
' ...
' -> Здесь код требующий измерений <-
' ...
   Gosub Time_stop              ' <-==== измерение производительности
   Gosub Time_view              ' <-==== измерение производительности
Loop
End


Сами подпрограммы:

Код:
' /-==== измерение производительности ====-\
Time_start:
   Timer1 = 0
   Start Timer1
Return
Time_stop:
   Stop Timer1
   Tms = Timer1 / 31.250
   Tms = Tms + 0.5
   Tms_word = Int(tms)
Return
Time_view:
   Print "Total: " ; Tms_word ; " ms"
Return

Надо понимать, что код очень простой и не учитывает переключение диапазонов (мне как бы это было и не нужно).
Работает всё аппаратно, требуется только один из таймеров (в данном примере 16-и разрядный).

+3

28

RDW написал(а):

Код/идея весьма простая

Спасибо, в копилку возьму.

+1


Вы здесь » Программирование ATMEL в BASCOM. » FAQ по Bascom AVR и МК » Скорость работы операторов Bascom