Обсуждение Неожиданно (новый виток священной войны камней)

Юрий Ботов

Moderator
Команда форума
Насмотревшись на баталии на форумах решил сделать для себя хоть какое не слишком эмоциональное сравнение мелкопроцессоров. Некоторые результаты оказались весьма неожиданными для меня, поэтому решил "опубликовать". Может кто меня подправит.
Участники (ну то что у меня самого есть, чего нет не брал):
классика avr@16MHz, msp430x2xxx@25MHz,stm8x(0/1)xx@16Mhz,stm8x2xx@24MHz,cortex-m(0/3/7)от stm32, esp8xxx, esp32, cortex от rtl.
Что сравниваю? Берем один и тот же простой код на С и смотрим ассемблер после компилятора. По нему считаем такты. Зная такты и частоту - нахожу время исполнения, и кроме того имею количество байт в которое это все превратилось.
Вот код который я подсунул компилятору:
Код:
static char ac = 0;
static char bc = 1;
static int ai = 0;
static int bi = 1;
static long al = 0;
static long bl = 1;

static int counter;

int main(void)
{
    for(counter = 0; counter < 10; counter++)
    {
        ac += bc;
        ai += bi;
        al += bl;
    }
}
Однако реально анализировать будем только вот это:
ac += bc; /* 8 бит */
ai += bi; /* 16 бит */
al += bl; /* 32 бит */
Остальное нужно просто для того чтобы компилятор не вздумал оптимизировать то, что его не просят.
Ясно что результат будет тот же что и у других арифметических и логических операций.
Компиляторы: SDCC для stm8 и gcc для всего остального.
В квадратных скобках - такты. Листинги я немного подправлял ручками чтобы сделать поединообразнее,
заменял вручную безликие адреса (в том числе относительные-что разумеется не корректно) на имена переменных (без учета режима адресации).
Но код не трогал.
Поехали.

Начнем с классики..
Код:
  ;            test.c: 14: ac += bc;
  3a:    80 91 68 00     [3] lds    r24, _ac
  3e:    98 2f           [1] mov    r25, r24
  40:    80 91 60 00     [3] lds    r24, _bc   
  44:    89 0f           [1] add    r24, r25
  46:    80 93 68 00     [3] sts    _ac, r24   
  ;         test.c: 15: ai += bi;
  4a:    20 91 69 00     [3] lds    r18, _ai
  4e:    30 91 6a 00     [3] lds    r19, _ai+1
  52:    80 91 61 00     [3] lds    r24, _bi
  56:    90 91 62 00     [3] lds    r25, _bi+1
  5a:    82 0f           [1] add    r24, r18
  5c:    93 1f           [1] adc    r25, r19
  5e:    90 93 6a 00     [3] sts    _ai+1, r25
  62:    80 93 69 00     [3] sts    _ai, r24
  ;            test.c: 16: al += bl;
  66:    20 91 6b 00     [3] lds    r18, _al
  6a:    30 91 6c 00     [3] lds    r19, _al+1
  6e:    40 91 6d 00     [3] lds    r20, _al+2
  72:    50 91 6e 00     [3] lds    r21, _al+3
  76:    80 91 63 00     [3] lds    r24, _bl
  7a:    90 91 64 00     [3] lds    r25, _bl+1
  7e:    a0 91 65 00     [3] lds    r26, _bl+2
  82:    b0 91 66 00     [3] lds    r27, _bl+3
  86:    82 0f           [1] add    r24, r18
  88:    93 1f           [1] adc    r25, r19
  8a:    a4 1f           [1] adc    r26, r20
  8c:    b5 1f           [1] adc    r27, r21
  8e:    80 93 6b 00     [3] sts    _al, r24
  92:    90 93 6c 00     [3] sts    _al+1, r25
  96:    a0 93 6d 00     [3] sts    _al+2, r26
  9a:    b0 93 6e 00     [3] sts    _al+3, r27
Команд: 29
Тактов: 71 (11/20/40) ТУТ И ДАЛЕЕ - сначала общее количество тактов потом отдельно на 8/16/32 битное сложение
Байт кода: 100
Тактовая частота: 16 МГц
Время исполнения: 4.43 мкс (0.69/1.25/2.5) ТУТ И ДАЛЕЕ - аналогично тактам
"Разочарование года".
 

Юрий Ботов

Moderator
Команда форума
ПРОДОЛЖЕНИЕ

Модное творение TI...
Код:
  ;            test.c: 14: ac += bc;
   c:    5f 42 00 00     [3] mov.b &ac, r15   
  10:    4e 4f           [1] mov.b r15, r14   
  12:    5f 42 00 00     [3] mov.b &bc, r15   
  16:    4f 5e           [1] add.b r14, r15   
  18:    c2 4f 00 00     [3] mov.b r15, &ac
  ;         test.c: 15: ai += bi;
  1c:    1e 42 00 00     [3] mov   &ai, r14   
  20:    1f 42 00 00     [3] mov   &bi, r15   
  24:    0f 5e           [1] add   r14, r15   
  26:    82 4f 00 00     [3] mov   r15, &ai
  ;            test.c: 16: al += bl;
  2a:    1c 42 00 00     [3] mov   &al, r12   
  2e:    1d 42 00 00     [3] mov   &al+2, r13   
  32:    1e 42 00 00     [3] mov   &bl, r14   
  36:    1f 42 00 00     [3] mov   &bl+2, r15   
  3a:    0e 5c           [1] add   r12, r14   
  3c:    0f 6d           [1] addc  r13, r15   
  3e:    82 4e 00 00     [3] mov   r14, &al   
  42:    82 4f 00 00     [3] mov   r15, &al+2
Команд: 17
Тактов: 41 (11/10/20)
Байт кода: 58
msp430g2xxx -
Тактовая частота: 16 МГц
Время исполнения: 2.56 мкс (0.69/0.62/1.25)
msp430g5xxx -
Тактовая частота: до 25 МГц
Время исполнения: 1.64 мкс (0.44/0.4/0.8)
Похоже, что знаменитое мизерное потребление достигнуто путем низкой производительности помноженной на мизерное количество ОЗУ...

Устаревшая, как говорят, архитектура...
Код:
  ;            test.c: 14: ac += bc;
    000006 C6u00u00         [ 1]  ld   a, _ac+0
    000009 CBu00u01         [ 1]  add  a, _bc+0
    00000C C7u00u00         [ 1]  ld   _ac+0, a
  ;            test.c: 15: ai += bi;
    00000F CEu00u02         [ 2]  ldw  x, _ai+0
    000012 72 BBu00u04      [ 2]  addw x, _bi+0
    000016 CFu00u02         [ 2]  ldw  _ai+0, x
  ;            test.c: 16: al += bl;
    000019 CEu00u08         [ 2]  ldw  x, _al+2
    00001C 72 BBu00u0C      [ 2]  addw x, _bl+2
    000020 C6u00u07         [ 1]  ld   a, _al+1
    000023 C9u00u0B         [ 1]  adc  a, _bl+1
    000026 90 97            [ 1]  ld   yl, a
    000028 C6u00u06         [ 1]  ld   a, _al+0
    00002B C9u00u0A         [ 1]  adc  a, _bl+0
    00002E 90 95            [ 1]  ld   yh, a
    000030 CFu00u08         [ 2]  ldw  _al+2, x
    000033 90 CFu00u06      [ 2]  ldw  _al+0, y
Команд: 16
Тактов: 23 (3/6/14)
Байт кода: 49
stm8x0xx, stm8x0xx -
Тактовая частота: до 16 МГц
Время исполнения: 1.44 мкс (0.19/0.38/0.87)
stm8x2xx -
Тактовая частота: до 24 МГц
Время исполнения: 0.96 мкс (0.12/0.24/0.58)
Ни чего себе...
 

Юрий Ботов

Moderator
Команда форума
ПРОДОЛЖЕНИЕ

А теперь сам великий...
Код:
    ;            test.c: 14: ac += bc;
   c:    4b12              ldr     r3, [pc, #_ac]
   e:    781a          [3] ldrb    r2, [r3, #0]
  10:    4b12              ldr        r3, [pc, #_bc]
  12:    781b          [3] ldrb    r3, [r3, #0]
  14:    4413          [1] add        r3, r2
  16:    b2da          [1] uxtb    r2, r3
  18:    4b0f              ldr        r3, [pc, #_ac]
  1a:    701a          [3] strb    r2, [r3, #0]
  ;         test.c: 15: ai += bi;
  1c:    4b10              ldr        r3, [pc, #_ai]
  1e:    681a          [3] ldr        r2, [r3, #0]
  20:    4b10              ldr        r3, [pc, #_bi]
  22:    681b          [3] ldr        r3, [r3, #0]
  24:    4413          [1] add        r3, r2
  26:    4a0e              ldr        r2, [pc, #_ai]
  28:    6013          [3] str        r3, [r2, #0]
  ;          test.c: 16: al += bl;
  2a:    4b0f              ldr        r3, [pc, #_al]
  2c:    681a          [3] ldr        r2, [r3, #0]
  2e:    4b0f              ldr        r3, [pc, #_bl]
  30:    681b          [3] ldr        r3, [r3, #0]
  32:    4413          [1] add        r3, r2
  34:    4a0c              ldr        r2, [pc, #_al]
  36:    6013          [3] str        r3, [r2, #0]
Команд: 22
Тактов: 31 (11/10/10)
Байт кода: 44
stm32x0xx -
Тактовая частота: 48 Мгц
Время исполнения: 0.65 мкс (0.23/0.21/0.21)
stm32x1xx -
Тактовая частота: 72 Мгц
Время исполнения: 0.43 мкс (0.15/0.14/0.14)
stm32x7xx -
Тактовая частота: 216 Мгц
Время исполнения: 0.14 мкс (0.051/0.046/0.046)
rtlXXXX -
Тактовая частота: 80 Мгц
Время исполнения: 0.39 мкс (0.14/0.13/0.13)
Рекордсмен по компактности кода? Не ожидал.

Ну и как же без...
Код:
  ;            test.c: 14: ac += bc;
  11:    000021            [4] l32r    a2, _ac
  14:    000232            [3] l8ui    a3, a2, 0
  17:    000021            [4] l32r    a2, _bc
  1a:    000222            [3] l8ui    a2, a2, 0
  1d:    232a              [3] add.n   a2, a3, a2
  1f:    743020            [3] extui   a3, a2, 0, 8
  22:    000021            [4] l32r    a2, _ac
  25:    004232            [3] s8i     a3, a2, 0
  ;         test.c: 15: ai += bi;
  28:    000021            [4] l32r    a2, _ai
  2b:    0238              [3] l32i.n  a3, a2, 0
  2d:    000021            [4] l32r    a2, _bi
  30:    0228              [3] l32i.n  a2, a2, 0
  32:    332a              [3] add.n   a3, a3, a2
  34:    000021            [4] l32r    a2, _ai
  37:    0239              [3] s32i.n  a3, a2, 0
  ;          test.c: 16: al += bl;
  39:    000021            [4] l32r    a2, _al
  3c:    0238              [3] l32i.n  a3, a2, 0
  3e:    000021            [4] l32r    a2, _bl
  41:    0228              [3] l32i.n  a2, a2, 0
  43:    332a              [3] add.n   a3, a3, a2
  45:    000021            [4] l32r    a2, _al
  48:    0239              [3] s32i.n   a3, a2, 0
Команд: 22
Тактов: 75 (27/24/24)
Байт кода: 57
esp8266 -
Тактовая частота: 80 Мгц
Время исполнения: 0.93 мкс (0.34/0.3/0.3)
Серенько.

Ну и...
Код:
  ;            test.c: 14: ac += bc;
   f:    002100            [4] l32r    a2, _ac
  12:    023200            [3] l8ui    a3, a2, 0
  15:    002100            [4] l32r    a2, _bc
  18:    022200            [3] l8ui    a2, a2, 0
  1b:    232a00            [3] add.n   a2, a3, a2
  1e:    743020            [3] extui   a3, a2, 0, 8
  21:    000021            [4] l32r    a2, _ac
  24:    004232            [3] s8i     a3, a2, 0
  ;         test.c: 15: ai += bi;
  27:    000021            [4] l32r    a2, _ai
  2a:    0238              [3] l32i.n  a3, a2, 0
  2c:    000021            [4] l32r    a2, _bi
  2f:    0228              [3] l32i.n  a2, a2, 0
  31:    332a              [3] add.n   a3, a3, a2
  33:    000021            [4] l32r    a2, _ai
  36:    0239              [3] s32i.n  a3, a2, 0
  ;          test.c: 16: al += bl;
  38:    000021            [4] l32r    a2, _al
  3b:    0238              [3] l32i.n  a3, a2, 0
  3d:    000021            [4] l32r    a2, _bl
  40:    0228              [3] l32i.n  a2, a2, 0
  42:    332a              [3] add.n   a3, a3, a2
  44:    000021            [4] l32r    a2, _al
  47:    0239              [3] s32i.n  a3, a2, 0
Команд: 22
Тактов: 75 (27/24/24)
Байт кода: 58
esp32 -
Тактовая частота: 80 Мгц
Время исполнения: 0.93 мкс (0.34/0.3/0.3)
Без изменений..
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
ОКОНЧАНИЕ

И что-же мы имеем?
По размеру кода во флэше от худшего к лучшему:
Код:
avr              100
xtensa            58
msp430            58
stm8              49
arm-cortrex       44
По времени выполнения всех трех сложений от худшего к лучшему:
Код:
avr@16MHz:              4.43
msp430g2@16MHz:         2.56
msp430g5@25MHz:         1.64
stm8x0xx/stm8x1xx@16MHz:1.44
stm8x2xx@24MHz:         0.96
xtensa@80MHz:           0.93
cortex-m0-stm32@48MHz:  0.65
cortex-m3-stm32@72MHz:  0.43
cortex-m3-rtl@80MHz:    0.39
cortex-m7-stm32@216MHz: 0.14
По времени выполнения 8 битного сложения от худшего к лучшему:
Код:
avr:                    0.69
msp430g2:               0.69
msp430g5:               0.44
xtensa:                 0.34
cortex-m0-stm32:        0.23
stm8x0xx/stm8x1xx:      0.19
cortex-m3-stm32:        0.15
cortex-m3-rtl:          0.14
stm8x2xx:               0.12
cortex-m7-stm32:        0.051
По времени выполнения 16 битного сложения от худшего к лучшему:
Код:
avr:                    1.25
msp430g2:               0.62
msp430g5:               0.4
stm8x0xx/stm8x1xx:      0.38
xtensa:                 0.3
stm8x2xx:               0.24
cortex-m0-stm32:        0.21
cortex-m3-stm32:        0.14
cortex-m3-rtl:          0.13
cortex-m7-stm32:        0.046
По времени выполнения 32 битного сложения от худшего к лучшему:
Код:
avr:                    2.5
msp430g2:               1.25
stm8x0xx/stm8x1xx:      0.87
msp430g5:               0.8
stm8x2xx:               0.58
xtensa:                 0.3
cortex-m0-stm32:        0.21
cortex-m3-stm32:        0.14
cortex-m3-rtl:          0.13
cortex-m7-stm32:        0.046
Да... конечно это все чушь, по хtens-ам я усреднил задержки при обращении к памяти до 1 такта,
а они могут быть от 0 до 2-х в зависимости от наличия в кэше. По по кортексам тоже наличие кэша не учитываю.
Все это не реальные измерения на железе, а просто подсчет тактов по документации.
Ну и дураку понятно, что минимальная инициализация у кортесов значительно больше чем у 8-битников, так что для малого
пользовательского кода вся кортексовская компактность "уйдет в гудок". В общем все совсем не однозначно.
Ну, в общем, поправьте меня кто как может :)
 
Последнее редактирование:
  • Like
Реакции: A_D

pvvx

Активный участник сообщества
Народ давно сравнивает в тестах и есть списки разных MCU.
К примеру в Dhrystone Benchmark, Version 2.1 (Language: C). Dhrystone 2.1 on mcus - Page 1
RTL-ки серии "A" (Аналог Cortex-M3) в SRAM (не в TCM!) под RTOS:
Код:
Dhrystones per Second:                      140706.343750
Dhrystones per MHz:                         844.238037
80.083292 DMIPS, 0.480500 DMIPS/MHz ?
BitBand на RTL8710AF (CPU 83.3MHz) ~1.5MHz, для остальной серии с базой в 166MHz -> ~3MHz

RTL-ки серии "B" (Аналог Cortex-M4 + FPU), исполнение из Flash под RTOS:
Код:
Dhrystone Benchmark, Version 2.1 (Language: C) (IAR compiler, SDK 4.0)
RunTime 6 544 ms, CPU CLK 125.000 000 MHz, Run Cycles 1 000 000
Microseconds for one run through Dhrystone: 6.544 000
Dhrystones per Second: 152 811.734 375
Dhrystones per MHz: 1 222.493 896
Analysis of the performance of the new generation of 32-bit Microcontrollers for IoT and Big Data Application (PDF Download Available)
Dhrystone Benchmark

Странно, но в тестах ни у кого нет ESP. Я тоже не стал портить эту картину :)

Пока чаще лидировал Microchip, из-за 2 команда на такт... Из-за этого сложно их сравнивать, т.к. данные пишут в 2 раза больше или считают как 1:1 по внутреннему стробу CPU... Частота работы CPU - понятие виртуальное (рекламное)... (Тут надо сравнивать потребление на команду. Лидировать, при схожести уровня технологии изготовления в микронах, будет скорее всего ARM.)
В Дристонах деленных на частоту и сравнивают. Для него есть базы и со времен PC на 8086 :) и перевод в другие единицы.
Следующие версии Dhrystone уже используют плавучку и не годятся для младших MCU...

Объем пользовательского кода в WiFi-SoC и инициализацию сравнивать нет смысла. Тут явно лидирует RTL871xBx - у него всё с собой - полный и рабочий (!) API на борту в ROM.

PS: Ещё детские замеры: Вычисляем число Пи на разных платформах! Тут RTL-ки серии "B" (Cortex-M4F) не сравнить, т.к. есть FPU, а без него любые rtl/stm почему-то* сильно быстрее ESP.

*'почему-то' связано с Non_OS_SDK и беспорядочными вставками исполнения delay(x) в либах Arduino для вызовов системных событий, а у других используется RTOS.
 
Последнее редактирование:
  • Like
Реакции: A_D

pvvx

Активный участник сообщества
Профессиональные бенчмарки можно посмотреть здесь: EEMBC
Там измерения в других попугаях и там нет ESP. Он же для профессионалов Arduino, по вашем типу :)
А для других WiFi-SoC измерений не требуется, т.к. там стандартный M3 или M4F.

Сами бенчмарки тут никому не нужны. Смысл в том, чтобы знать какова будет скорость выполнения у данного CPU WiFi-SoC по известному стандартному и готовому алгоритму. На ESP по данному поводу имеем ноль информации, что не сказать о других. Это влияет на выбор алгоритмов применяемых в проекте и вообще тех. маркетинг. проекта. ESP не входят в сферу профессиональных разработок.

Как пример – потребовалось создать беспроводный сбор данных с датчиков в хорошем разрешении – взял RTL и стандартные либы на asm преобразований Фурье, да поглядел описание к ним – сколько там требуется тактов. Под это взял 24 бит ADC c 250 ksps, т.к. более не треба и слепил. На ESP рассчитать или даже предварительно прикунуть какая выйдет производительность и что туда пойдет не возможно.
 
Последнее редактирование:
Сверху Снизу