В этой статье протестируем 3-и компилятора для микроконтроллеров Kinetis с ядром ARM Cortex-M4.
Запустим тесты CoreMark, Whetstone, Dhrystone.
Исследуем алгоритмы сжатия с минимальным потреблением ОЗУ и выясним как влияют на их быстродействие разные компиляторы.
И даже попытаемся узнать насколько отстает Kinetis по быстродействию от Intel Core I7.




Предыдущие статьи о разработке на микроконтроллерах Kinetis:



В статье “Начало разработки на микроконтроллерах Kinetis. Быстрый старт” была описана среда разработки Kinetis Design Studio v3.0.0 (KDS). Среда KDS использует в качестве инструмента компиляции и сборки программного обеспечения пакет GNU Tools for ARM Embedded Processors. Туда в частности входит компилятор GCC для ARM. Компилятор неплохой во всех смыслах. Но если мы посмотрим сколько существует у него ветвей в директории gcc.gnu.org/svn/gcc/branches, то увидим их более 300! Сколько же сил надо чтобы поддерживать такое огромное количество ветвей!? А ведь проект не коммерческий. С другой стороны серия ARM Cortex-M не мэйнстрим, не используются в смартфонах, к ним не привлечено так много внимания сообщества поддерживающего Open Source.

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

К счастью KDS обеспечена плагинами для конвертации под другие известные пакеты компиляции и сборки — Keil и IAR. Большинство демо-проектов для Kinetis сопровождается 3-мя конфигурациями для сборки средствами GCC, Keil и IAR. Однако в наборе программного обеспечения для Kinetis нет достаточно всеобъемлющего теста для сравнения этих инструментов компиляции между собой. Поэтому пришлось создать свой.
Проект создан в KDS с использованием плагина ProcessorExpert для микроконтроллера MK60FN1M0VLQ12 на плате представленной в статье “Умная плата для управления силовыми 3-х фазными нагрузками”

Вот экран проекта в KDS:


Что входит в пакет тестов


Проект Whetstone . Очень старый и простой тест производительности вычислений с плавающей точкой. Тест очень легко портируется и может выполняться на простейших микроконтроллерах. В нашем случае представлено две реализации: вариант вычислений c типом float и вариант с типом double. Это важно, поскольку в первом случае у Cortex-M4 используется сопроцессор, а во втором нет.

Проект Dhrystone. Тест производительности целочисленных операций. Типы float и double нигде не применяются. Тест тоже легко портируется и имеется огромный архив результатов для всевозможных микроконтроллеров и компьютеров.

Проект CoreMark. Современный тест, специально разработанный для встраиваемых систем. Может стать индустриальным стандартом. Его результаты сертифицируются организацией EEMBC, а значит защищены в какой-то мере от читинга и фальсификации.
Результаты теста CoreMark вызывают наибольшее доверие при комплексном тестировании производительности микроконтроллеров и сравнении компиляторов. На нем в принципе можно было бы и ограничится, но тесты сами по себе не несут никакой практической пользы для встраиваемых приложений, и чтобы придать большее прикладное значение этим тестам я добавил еще тестирование алгоритмов сжатия.

Для начала пришлось найти подходящий менеджер памяти (менеджер кучи или heap).

Проект umm_malloc. Нашелся на Github. С виду показался вполне подходящим. Стандартный менеджер кучи из библиотеки C-и я использовать отказался по двум причинам. Во-первых, в каждой из сред Keil, IAR, GCC будет своя библиотека кучи и не хотелось тратить время на исследование особенностей каждой из них. Во-вторых, алгоритмы сжатия критически зависят от объемы выделяемой им памяти. А памяти в обрез. Нужен был механизм точного контроля выделяемой памяти. И здесь umm_malloc предоставляет такую возможность. А попутно мы протестируем и быстродействие самого алгоритма umm_malloc.

Алгоритмы сжатия


Все алгоритмы пришлось подстраивать для того чтобы они использовали как можно меньше ОЗУ.
Сколько памяти нужно этим алгоритмам, насколько они могут сжать данные и каково их быстродействие можно посмотреть в результатах тестов и в листинге вывода в терминал.

А вот результаты:


-У всех компиляторов была включена опция максимальной оптимизации. Точный состав опций можно посмотреть в прилагающемся проекте.
-Алгоритмы сжатия сжимали участок бинарного кода прошивки, полученной из проекта этого теста, скомпилированного в IAR.
-Время компиляции GCC измерено при компиляции из среды KDS.
-Помимо скорости работы алгоритмов также в таблицу вставлены строчки с дополнительными важными для разработчика метриками, это: время полной перекомпиляции проекта, размер бинарного файла при оптимизации по скорости и размер бинарного файла при оптимизации по размеру.

Вывод в терминал результатов теста скомпилированного в IAR
----------- Speed Test -------------


Reference time = 100001 us

----------- umm malloc test -------------
...........................................................
|0x1fff1b44|B     0|NB     1|PB     0|Z     1|NF     1|PF     0|USED
|0x1fff1b4c|B     1|NB  4223|PB     0|Z  4222|NF  4223|PF     0|FREE
|0x1fff9f3c|B  4223|NB     0|PB     1|Z     1|NF     0|PF     1|USED
...........................................................
Total Entries     1    Used Entries      0    Free Entries      1
Total Blocks   4223    Used Blocks       0    Free Blocks    4223
                       Used space =      0    Free space =  33784
...........................................................

umm malloc test   time  = 1447071 uS
Allocations =  40000, uSec per allocation = 36

----------- Compressor LZSS test -------------
Uncompressed size = 2048
Compressed   size = 1858. Max. alloc.= 14384. Time = 6627 uS
Decompress                Max. alloc.= 1048. Time = 981 uS
Decompress Ok!

----------- Compressor Zlib test -------------
Uncompressed size = 2048
Compressed   size = 1740. Max. alloc.= 24288. Time = 12179 uS
Decompress                Max. alloc.= 15768. Time = 764 uS
Decompress Ok!

----------- Compressor S-LZW test -------------
Uncompressed size = 2048
Compressed   size = 2035. Max. alloc.= 4320. Time = 2542 uS
Decompress                Max. alloc.= 4320. Time = 3816 uS
Decompress Ok!

----------- Compressor FastLZ test -------------
Uncompressed size = 2048
Compressed   size = 1834. Max. alloc.= 32776. Time = 1010 uS
Decompress                Max. alloc.= 0. Time = 152 uS
Decompress Ok!


----------- WHETSTONE FLOAT -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679254770278930664
  xx2  = -0.46633863449096679688
  xx3  = -0.73303699493408203125
  xx4  = -1.13254797458648681641
.........MODULE 2:  array elements.......
  e10  = -0.06834230571985244751
  e11  = -0.46263590455055236816
  e12  = -0.72971796989440917969
  e13  = -1.12397670745849609375
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533060804009437561
  e1_1 = -0.44743216037750244141
  e1_2 = -0.71096724271774291992
  e1_3 = -1.10309338569641113281
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49041154980659484863
  y1   = 0.49039667844772338867
.........MODULE 8:  procedure calls......
  z    = 0.99993747472763061523
.........MODULE9:  array references......
  e1_j = -1.10309338569641113281
  e1_k = 3.00000000000000000000
  e1_l = -1.10309338569641113281
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466047048568725586
........................................
Whetstone last    time (uS) = 10960.00
Whetstone max     time (uS) = 10961.00
Whetstone min     time (uS) = 10960.00


----------- WHETSTONE DOUBLE -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679268039452399826
  xx2  = -0.46633881454398036003
  xx3  = -0.73303694842681344599
  xx4  = -1.13254799829068817198
.........MODULE 2:  array elements.......
  e10  = -0.06834219862995164003
  e11  = -0.46263765626356890425
  e12  = -0.72971838784369053319
  e13  = -1.12397907004612833261
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533645259179445915
  e1_1 = -0.44743656275474680588
  e1_2 = -0.71097338928518248722
  e1_3 = -1.10309805692560095340
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040731615907084197
  y1   = 0.49039249795612543821
.........MODULE 8:  procedure calls......
  z    = 0.99993750062499996275
.........MODULE9:  array references......
  e1_j = -1.10309805692560095340
  e1_k = 3.00000000000000000000
  e1_l = -1.10309805692560095340
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466551951904967427
........................................
Whetstone last    time (uS) = 142583.00
Whetstone max     time (uS) = 142583.00
Whetstone min     time (uS) = 142582.00


----------- DHRYSTONE 2 -------------


Dhrystone Benchmark, Version 2.1 (Language: C)
Program compiled without 'register' attribute
Execution starts, 20000 runs through Dhrystone
                                              Execution ends
Final values of the variables used in the benchmark:
Int_Glob:            5
        should be:   5
Bool_Glob:           1
        should be:   1
Ch_1_Glob:           A
        should be:   A
Ch_2_Glob:           B
        should be:   B
Arr_1_Glob[8]:       7
        should be:   7
Arr_2_Glob[8][7]:    20010
        should be:   Number_Of_Runs + 10
Ptr_Glob->
  Ptr_Comp:          536867932
        should be:   (implementation-dependent)
  Discr:             0
        should be:   0
  Enum_Comp:         2
        should be:   2
  Int_Comp:          17
        should be:   17
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
  Ptr_Comp:          536867932
        should be:   (implementation-dependent), same as above
  Discr:             0
        should be:   0
  Enum_Comp:         1
        should be:   1
  Int_Comp:          18
        should be:   18
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc:           5
        should be:   5
Int_2_Loc:           13
        should be:   13
Int_3_Loc:           7
        should be:   7
Enum_Loc:            1
        should be:   1
Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
        should be:   DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
        should be:   DHRYSTONE PROGRAM, 2'ND STRING
Time = 93000 us
Microseconds for one run through Dhrystone: 4.65
Dhrystones per Second:                      215053


----------- COREMARK -------------

2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 29079282
Total time (secs): 29.079282
Iterations/Sec   : 343.887445
Iterations       : 10000
Compiler version : IAR 7.40.7
Compiler flags   :  -O3 -Otime
Memory location  : IRAM
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x988c
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 343.887445 / IAR 7.40.7  -O3 -Otime / IRAM

END.


Вывод в терминал результатов теста скомпилированного в Keil
----------- Speed Test -------------


Reference time = 100001 us

----------- umm malloc test -------------
...........................................................
|0x1fff60f8|B     0|NB     1|PB     0|Z     1|NF     1|PF     0|USED
|0x1fff6100|B     1|NB  4223|PB     0|Z  4222|NF  4223|PF     0|FREE
|0x1fffe4f0|B  4223|NB     0|PB     1|Z     1|NF     0|PF     1|USED
...........................................................
Total Entries     1    Used Entries      0    Free Entries      1
Total Blocks   4223    Used Blocks       0    Free Blocks    4223
                       Used space =      0    Free space =  33784
...........................................................

umm malloc test   time  = 1507118 uS
Allocations =  40000, uSec per allocation = 37

----------- Compressor LZSS test -------------
Uncompressed size = 2048
Compressed   size = 1858. Max. alloc.= 14384. Time = 7406 uS
Decompress                Max. alloc.= 1048. Time = 989 uS
Decompress Ok!

----------- Compressor Zlib test -------------
Uncompressed size = 2048
Compressed   size = 1740. Max. alloc.= 24288. Time = 11716 uS
Decompress                Max. alloc.= 15768. Time = 912 uS
Decompress Ok!

----------- Compressor S-LZW test -------------
Uncompressed size = 2048
Compressed   size = 2035. Max. alloc.= 4320. Time = 2839 uS
Decompress                Max. alloc.= 4320. Time = 4194 uS
Decompress Ok!

----------- Compressor FastLZ test -------------
Uncompressed size = 2048
Compressed   size = 1834. Max. alloc.= 32776. Time = 1028 uS
Decompress                Max. alloc.= 0. Time = 160 uS
Decompress Ok!


----------- WHETSTONE FLOAT -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679254770278930700
  xx2  = -0.46633863449096680000
  xx3  = -0.73303699493408203000
  xx4  = -1.13254797458648680000
.........MODULE 2:  array elements.......
  e10  = -0.06834230571985244800
  e11  = -0.46263590455055237000
  e12  = -0.72971796989440918000
  e13  = -1.12397670745849610000
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533060804009437600
  e1_1 = -0.44743216037750244000
  e1_2 = -0.71096724271774292000
  e1_3 = -1.10309338569641110000
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040567874908447000
  y1   = 0.49039086699485779000
.........MODULE 8:  procedure calls......
  z    = 0.99993747472763062000
.........MODULE9:  array references......
  e1_j = -1.10309338569641110000
  e1_k = 3.00000000000000000000
  e1_l = -1.10309338569641110000
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466011285781860000
........................................
Whetstone last    time (uS) = 08925.00
Whetstone max     time (uS) = 08926.00
Whetstone min     time (uS) = 08925.00


----------- WHETSTONE DOUBLE -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679268039452399000
  xx2  = -0.46633881454398041000
  xx3  = -0.73303694842681344000
  xx4  = -1.13254799829068810000
.........MODULE 2:  array elements.......
  e10  = -0.06834219862995163900
  e11  = -0.46263765626356895000
  e12  = -0.72971838784369047000
  e13  = -1.12397907004612830000
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533645259179446200
  e1_1 = -0.44743656275474680000
  e1_2 = -0.71097338928518250000
  e1_3 = -1.10309805692560080000
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040731615903904000
  y1   = 0.49039249795609352000
.........MODULE 8:  procedure calls......
  z    = 0.99993750062499998000
.........MODULE9:  array references......
  e1_j = -1.10309805692560080000
  e1_k = 3.00000000000000000000
  e1_l = -1.10309805692560080000
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466551951905033000
........................................
Whetstone last    time (uS) = 166298.00
Whetstone max     time (uS) = 166298.00
Whetstone min     time (uS) = 166298.00


----------- DHRYSTONE 2 -------------


Dhrystone Benchmark, Version 2.1 (Language: C)
Program compiled without 'register' attribute
Execution starts, 20000 runs through Dhrystone
                                              Execution ends
Final values of the variables used in the benchmark:
Int_Glob:            5
        should be:   5
Bool_Glob:           1
        should be:   1
Ch_1_Glob:           A
        should be:   A
Ch_2_Glob:           B
        should be:   B
Arr_1_Glob[8]:       7
        should be:   7
Arr_2_Glob[8][7]:    20010
        should be:   Number_Of_Runs + 10
Ptr_Glob->
  Ptr_Comp:          536870816
        should be:   (implementation-dependent)
  Discr:             0
        should be:   0
  Enum_Comp:         2
        should be:   2
  Int_Comp:          17
        should be:   17
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
  Ptr_Comp:          536870816
        should be:   (implementation-dependent), same as above
  Discr:             0
        should be:   0
  Enum_Comp:         1
        should be:   1
  Int_Comp:          18
        should be:   18
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc:           5
        should be:   5
Int_2_Loc:           13
        should be:   13
Int_3_Loc:           7
        should be:   7
Enum_Loc:            1
        should be:   1
Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
        should be:   DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
        should be:   DHRYSTONE PROGRAM, 2'ND STRING
Time = 91000 us
Microseconds for one run through Dhrystone: 4.55
Dhrystones per Second:                      219780


----------- COREMARK -------------

2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 37386523
Total time (secs): 37.386523
Iterations/Sec   : 267.476064
Iterations       : 10000
Compiler version : armcc V5.06 (build 20)
Compiler flags   :  -O3 -Otime
Memory location  : IRAM
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x988c
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 267.476064 / armcc V5.06 (build 20)  -O3 -Otime / IRAM

END.


Вывод в терминал результатов теста скомпилированного в GCC
----------- Speed Test -------------


Reference time = 100001 us

----------- umm malloc test -------------
...........................................................
|0x1fff5280|B     0|NB     1|PB     0|Z     1|NF     1|PF     0|USED
|0x1fff5288|B     1|NB  4223|PB     0|Z  4222|NF  4223|PF     0|FREE
|0x1fffd678|B  4223|NB     0|PB     1|Z     1|NF     0|PF     1|USED
...........................................................
Total Entries     1    Used Entries      0    Free Entries      1
Total Blocks   4223    Used Blocks       0    Free Blocks    4223
                       Used space =      0    Free space =  33784
...........................................................

umm malloc test   time  = 983944 uS
Allocations =  40000, uSec per allocation = 24

----------- Compressor LZSS test -------------
Uncompressed size = 2048
Compressed   size = 1858. Max. alloc.= 14384. Time = 8504 uS
Decompress                Max. alloc.= 1048. Time = 673 uS
Decompress Ok!

----------- Compressor Zlib test -------------
Uncompressed size = 2048
Compressed   size = 1740. Max. alloc.= 24288. Time = 12384 uS
Decompress                Max. alloc.= 15768. Time = 1070 uS
Decompress Ok!

----------- Compressor S-LZW test -------------
Uncompressed size = 2048
Compressed   size = 2035. Max. alloc.= 4320. Time = 2577 uS
Decompress                Max. alloc.= 4320. Time = 4189 uS
Decompress Ok!

----------- Compressor FastLZ test -------------
Uncompressed size = 2048
Compressed   size = 1834. Max. alloc.= 32776. Time = 1045 uS
Decompress                Max. alloc.= 0. Time = 234 uS
Decompress Ok!


----------- WHETSTONE FLOAT -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679254770278930664
  xx2  = -0.46633863449096679688
  xx3  = -0.73303699493408203125
  xx4  = -1.13254797458648681641
.........MODULE 2:  array elements.......
  e10  = -0.06834230571985244751
  e11  = -0.46263590455055236816
  e12  = -0.72971796989440917969
  e13  = -1.12397670745849609375
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533138290047645569
  e1_1 = -0.44743290543556213379
  e1_2 = -0.71096915006637573242
  e1_3 = -1.10309529304504394531
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040564894676208496
  y1   = 0.49039086699485778809
.........MODULE 8:  procedure calls......
  z    = 0.99993747472763061523
.........MODULE9:  array references......
  e1_j = -1.10309529304504394531
  e1_k = 3.00000000000000000000
  e1_l = -1.10309529304504394531
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466064929962158203
........................................
Whetstone last    time (uS) = 13629.00
Whetstone max     time (uS) = 13630.00
Whetstone min     time (uS) = 13629.00


----------- WHETSTONE DOUBLE -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679268039452398997
  xx2  = -0.46633881454398040667
  xx3  = -0.73303694842681343946
  xx4  = -1.13254799829068808492
.........MODULE 2:  array elements.......
  e10  = -0.06834219862995163930
  e11  = -0.46263765626356895266
  e12  = -0.72971838784369047470
  e13  = -1.12397907004612829240
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533645259179446191
  e1_1 = -0.44743656275474680273
  e1_2 = -0.71097338928518249990
  e1_3 = -1.10309805692560081170
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040731615904653573
  y1   = 0.49039249795610123650
.........MODULE 8:  procedure calls......
  z    = 0.99993750062499997533
.........MODULE9:  array references......
  e1_j = -1.10309805692560081170
  e1_k = 3.00000000000000000000
  e1_l = -1.10309805692560081170
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466551951905032514
........................................
Whetstone last    time (uS) = 219895.00
Whetstone max     time (uS) = 219895.00
Whetstone min     time (uS) = 219894.00


----------- DHRYSTONE 2 -------------


Dhrystone Benchmark, Version 2.1 (Language: C)
Program compiled without 'register' attribute
Execution starts, 20000 runs through Dhrystone
                                              Execution ends
Final values of the variables used in the benchmark:
Int_Glob:            5
        should be:   5
Bool_Glob:           1
        should be:   1
Ch_1_Glob:           A
        should be:   A
Ch_2_Glob:           B
        should be:   B
Arr_1_Glob[8]:       7
        should be:   7
Arr_2_Glob[8][7]:    20010
        should be:   Number_Of_Runs + 10
Ptr_Glob->
  Ptr_Comp:          536870792
        should be:   (implementation-dependent)
  Discr:             0
        should be:   0
  Enum_Comp:         2
        should be:   2
  Int_Comp:          17
        should be:   17
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
  Ptr_Comp:          536870792
        should be:   (implementation-dependent), same as above
  Discr:             0
        should be:   0
  Enum_Comp:         1
        should be:   1
  Int_Comp:          18
        should be:   18
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc:           5
        should be:   5
Int_2_Loc:           13
        should be:   13
Int_3_Loc:           7
        should be:   7
Enum_Loc:            1
        should be:   1
Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
        should be:   DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
        should be:   DHRYSTONE PROGRAM, 2'ND STRING
Time = 74000 us
Microseconds for one run through Dhrystone: 3.70
Dhrystones per Second:                      270270


----------- COREMARK -------------

2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 45291107
Total time (secs): 45.291107
Iterations/Sec   : 220.793897
Iterations       : 10000
Compiler version : GCC4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]
Compiler flags   :  -O3 -Otime
Memory location  : IRAM
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x988c
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 220.793897 / GCC4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]  -O3 -Otime / IRAM

END.


Вывод в терминал результатов теста запущенного в Visual Studio 2015
----------- Speed Test -------------


Reference time = 100000 us

----------- umm malloc test -------------
...........................................................
|0x00ba5980|B     0|NB     1|PB     0|Z     1|NF     1|PF     0|USED
|0x00ba5988|B     1|NB  4223|PB     0|Z  4222|NF  4223|PF     0|FREE
|0x00badd78|B  4223|NB     0|PB     1|Z     1|NF     0|PF     1|USED
...........................................................
Total Entries     1    Used Entries      0    Free Entries      1
Total Blocks   4223    Used Blocks       0    Free Blocks    4223
                       Used space =      0    Free space =  33784
...........................................................

umm malloc test   time  = 13586 uS
Allocations =  40000, uSec per allocation = 0

----------- Compressor LZSS test -------------
Uncompressed size = 2048
Compressed   size = 1858. Max. alloc.= 14384. Time = 146 uS
Decompress                Max. alloc.= 1048. Time = 10 uS
Decompress Ok!

----------- Compressor Zlib test -------------
Uncompressed size = 2048
Compressed   size = 1740. Max. alloc.= 24288. Time = 241 uS
Decompress                Max. alloc.= 15768. Time = 20 uS
Decompress Ok!

----------- Compressor S-LZW test -------------
Uncompressed size = 2048
Compressed   size = 2035. Max. alloc.= 4320. Time = 47 uS
Decompress                Max. alloc.= 4320. Time = 31 uS
Decompress Ok!

----------- Compressor FastLZ test -------------
Uncompressed size = 2048
Compressed   size = 1834. Max. alloc.= 32776. Time = 13 uS
Decompress                Max. alloc.= 0. Time = 4 uS
Decompress Ok!


----------- WHETSTONE FLOAT -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679254770278930700
  xx2  = -0.46633863449096680000
  xx3  = -0.73303699493408203000
  xx4  = -1.13254797458648680000
.........MODULE 2:  array elements.......
  e10  = -0.06834230571985244800
  e11  = -0.46263590455055237000
  e12  = -0.72971796989440918000
  e13  = -1.12397670745849610000
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533060804009437600
  e1_1 = -0.44743216037750244000
  e1_2 = -0.71096724271774292000
  e1_3 = -1.10309338569641110000
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040612578392029000
  y1   = 0.49039128422737122000
.........MODULE 8:  procedure calls......
  z    = 0.99993747472763062000
.........MODULE9:  array references......
  e1_j = -1.10309338569641110000
  e1_k = 3.00000000000000000000
  e1_l = -1.10309338569641110000
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466225862503052000
........................................
Whetstone last    time (uS) = 00131.00
Whetstone max     time (uS) = 00168.00
Whetstone min     time (uS) = 00123.00


----------- WHETSTONE DOUBLE -------------

.........MODULE 1:  simple identifiers...
  xx1  = -0.06679268039452399000
  xx2  = -0.46633881454398041000
  xx3  = -0.73303694842681344000
  xx4  = -1.13254799829068810000
.........MODULE 2:  array elements.......
  e10  = -0.06834219862995163900
  e11  = -0.46263765626356895000
  e12  = -0.72971838784369047000
  e13  = -1.12397907004612830000
.........MODULE 3:  array as parameter...
  e1_0 = -0.05533645259179446200
  e1_1 = -0.44743656275474680000
  e1_2 = -0.71097338928518250000
  e1_3 = -1.10309805692560080000
.........MODULE 4:  conditional jumps....
  val  = 1
.........MODULE 6:  integer arithmetic...
  e1k  = 6.00000000000000000000
  e1l  = 6.00000000000000000000
.........MODULE 7:  trig. functions......
  x1   = 0.49040731615904543000
  y1   = 0.49039249795610007000
.........MODULE 8:  procedure calls......
  z    = 0.99993750062499998000
.........MODULE9:  array references......
  e1_j = -1.10309805692560080000
  e1_k = 3.00000000000000000000
  e1_l = -1.10309805692560080000
.........MODULE10:  integer arithmetic...
  j    = 2
  k    = 3
.........MODULE11:  standard functions...
  x    = 0.83466551951905787000
........................................
Whetstone last    time (uS) = 00152.00
Whetstone max     time (uS) = 00186.00
Whetstone min     time (uS) = 00142.00


----------- DHRYSTONE 2 -------------


Dhrystone Benchmark, Version 2.1 (Language: C)
Program compiled without 'register' attribute
Execution starts, 20000 runs through Dhrystone
Execution ends
Final values of the variables used in the benchmark:
Int_Glob:            5
        should be:   5
Bool_Glob:           1
        should be:   1
Ch_1_Glob:           A
        should be:   A
Ch_2_Glob:           B
        should be:   B
Arr_1_Glob[8]:       7
        should be:   7
Arr_2_Glob[8][7]:    20010
        should be:   Number_Of_Runs + 10
Ptr_Glob->
  Ptr_Comp:          3602560
        should be:   (implementation-dependent)
  Discr:             0
        should be:   0
  Enum_Comp:         2
        should be:   2
  Int_Comp:          17
        should be:   17
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
  Ptr_Comp:          3602560
        should be:   (implementation-dependent), same as above
  Discr:             0
        should be:   0
  Enum_Comp:         1
        should be:   1
  Int_Comp:          18
        should be:   18
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc:           5
        should be:   5
Int_2_Loc:           13
        should be:   13
Int_3_Loc:           7
        should be:   7
Enum_Loc:            1
        should be:   1
Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
        should be:   DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
        should be:   DHRYSTONE PROGRAM, 2'ND STRING
Time = 551 us
Microseconds for one run through Dhrystone: 0.03
Dhrystones per Second:                      36297640


----------- COREMARK -------------

2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 11012043
Total time (secs): 11.012043
Iterations/Sec   : 9080.967083
Iterations       : 100000
Compiler version : VS 2013
Compiler flags   :  -O3 -Otime
Memory location  : IRAM
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0xd340
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 9080.967083 / VS 2015  -O3 -Otime / IRAM

END.



Как тут оказался Intel Core i7


Дело в том, что все алгоритмы сжатия и менеджер памяти отлаживались в среде Visual Studio и это процессор моего компьютера. В архиве есть директория SpeedTest_VS, где содержится проект для Visual Studio 2015 и в котором можно при желании продолжить совершенствование данных алгоритмов.

Вывод


IAR оказался безусловным лидером рейтинга. Самое удивительно что, сохраняя эффективность кода IAR также лидер и по скорости компиляции. Неучтенная здесь ложка дёгтя в том, что IAR поставляется с довольно мало функциональным редактором исходных текстов. Можно конечно запускать компиляцию инструментами IAR прямо из среды KDS, поскольку KDS это тот же слегка модифицированный Eclipse версии Mylyn. Но время перекомпиляции тогда увеличивается до 2 мин! У Eclipse тоже есть недостаток, он медленно открывается, с некоторого размера исходников у него начинает тормозиться контекстный парсинг. В проекте данного теста есть директория SpeedTest_SE. Там содержится файл SpeedTest.vpw рабочего пространства проекта данного теста для редактора SlickEdit. SlickEdit прекрасный, очень быстрый редактор, а IAR IDE умеет автоматически отслеживать изменения файлов, поэтому не возникает проблем в их совместном использовании.

Полный архив проекта (97.7 MB) доступен по ссылке https://drive.google.com/file/d/0B5dbvc_yPqJHYWI0OE9YZklKRjQ/view?usp=sharing

Комментарии (8)


  1. farcaller
    04.01.2016 01:45

    Еще хотелось бы clang увидеть рядом, конечно.


  1. Dark_Purple
    04.01.2016 10:30

    Что и требовалось доказать…


  1. Sergei2405
    04.01.2016 11:29
    +1

    www.ghs.com/products/compiler.html

    Вот этот компилятор еще бы попробовать.


  1. Elvish
    05.01.2016 11:39

    судя по тестам, у меня складывается ощущение, что gcc не подключил (или не использовал) сопроцессор.
    по времени компиляции для случая gcc можно попробовать указать системе сборки использовать параллельную компиляцию (make -j8 например), если это возможно.

    табличку тяжело изучать, так как в 1/3 случаев для случаев второго места — нет процентажа.


    1. Indemsys
      05.01.2016 18:18

      GCC сопроцессор подключил это можно увидеть в листинге ассемблера. В проекте все вложено.
      Сборка была из KDS, ничего другого не тестировалось.
      Таблица такая уж получилась. Не хотелось еще загромождать цифрами.


  1. monah_tuk
    05.01.2016 16:52

    Во-первых, в каждой из сред Keil, IAR, GCC будет своя библиотека кучи и не хотелось тратить время на исследование особенностей каждой из них
    Какая-то полумера. Нет, обоснование понятное: поставить в равные условия. Но ведь тогда нужно не использовать и libc, всякие libgcc, startfiles (серия опций -nostdlib -nostartfiles у GCC), предоставив единую реализацию. А то правильно, рантайм Kail, IAR заточен на embedded, а GCC всё же копилятор с более широким спектром поддерживаемых платформ. В нашем проекте пришлось выкидывать стандартный рантайм, т.к. весил очень много и писать свою функциональность, минимально-необходимую (по принципу: «что вылезет на линковке»). Сэкономили почти 100кБ (из 300 доступных, C++11). Хотя это и аффектит только последние два пункта. Но всё же. В остальном интересно размышление Elvish в geektimes.ru/post/264558/#comment_8934830. Ровно как и сборка вне IDE.

    ЗЫ традиционный риторический вопрос: это же про программирование, это же тематика хабра, не?


    1. Indemsys
      05.01.2016 18:20

      Нужна была библиотека работы с heap со способностью регистрировать утечки и расход памяти.
      К штатным пришлось бы к каждой писать свою обертку.


      1. monah_tuk
        06.01.2016 04:03

        Не-не-не, я это как раз понимаю и поддерживаю. Вопрос — почему остальной рантайм не унифицирован?