Реализация типа float24_t

А какие опции компиляции у тебя стоят?

Посмотри, когда компиляция идет, там строчки такие километровые ползут. Найди ту, где вызывается твой ???—???–g++, промотай ее вправо, поищи -Os. Если найдешь, то замени ее на -O3.

-Os по умолчанию стоит , например, на ЕСП32, подозреваю, что на АВР, с его крошечной памятью - тоже. Это оптимизация по размеру,в ущерб скорости. -O3 - умеренно агрессивная оптимизация по скорости, в ущерб размеру.

ЗЫЖ: Посмотри исходный код первого квейка. У них там кошерная фиксированная точка, (помойму, в 16 битах, но могу наврать).

Очень все быстро. И 1/sqrt(x) там есть супер быстрая реализация.

sizeof() от класса вернет строго размер данных класса.

Который у вас как раз три байта.

Как МММ уже указал - this в классе не хранится. Но даже если бы он и хранился, то sizeof() все равно вернет 3. Ровно столько, сколько вы указали.

какая-то фраза неаккуратная… Если бы… да кабы…

Если бы он хранился, то и сайз бы его показывал, наверно :slight_smile: Но если б this хранился в классе, это был бы уже другой язык.

Настройки по умолчанию -Os.
С опцией -O3 не собирается

Вывод компилятора
FQBN: arduino:avr:nano:cpu=atmega328old
использование платы 'nano' из платформы в каталоге: C:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6
Использование ядра 'arduino' из платформы в каталоге: C:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6

Обнаружение используемых библиотек...
C:\Users\Igor\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -O3 -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -IC:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino -IC:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\variants\eightanaloginputs C:\Users\Igor\AppData\Local\arduino\sketches\F960B7B623F068E480A31C4963CA01B2\sketch\Float24.ino.cpp -o nul
Использование кэшированных библиотечных зависимостей для файла: C:\Users\Igor\AppData\Local\arduino\sketches\F960B7B623F068E480A31C4963CA01B2\sketch\Benchmark.cpp
Создание прототипов функций...
C:\Users\Igor\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -O3 -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -IC:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino -IC:\Users\Igor\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\variants\eightanaloginputs C:\Users\Igor\AppData\Local\arduino\sketches\F960B7B623F068E480A31C4963CA01B2\sketch\Float24.ino.cpp -o C:\Users\Igor\AppData\Local\Temp\1785287194\sketch_merged.cpp
C:\Users\Igor\AppData\Local\Arduino15\packages\builtin\tools\ctags\5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives C:\Users\Igor\AppData\Local\Temp\1785287194\sketch_merged.cpp

Компиляция скетча...
"C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -O3 -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IC:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\eightanaloginputs" "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2\\sketch\\Float24.ino.cpp" -o "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2\\sketch\\Float24.ino.cpp.o"
Используем предварительно скомпилированный файл: C:\Users\Igor\AppData\Local\arduino\sketches\F960B7B623F068E480A31C4963CA01B2\sketch\Benchmark.cpp.o
Компиляция библиотек...
Компиляция ядра...
Использование предварительно скомпилированного ядра: C:\Users\Igor\AppData\Local\arduino\cores\arduino_avr_nano_cpu_atmega328old_8acf3edbb9dcbc0699dc5972e0e8a60c\core.a
Связывается все вместе...
"C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -Wall -Wextra -O3 -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2/Float24.ino.elf" "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2\\sketch\\Benchmark.cpp.o" "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2\\sketch\\Float24.ino.cpp.o" "C:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2/..\\..\\cores\\arduino_avr_nano_cpu_atmega328old_8acf3edbb9dcbc0699dc5972e0e8a60c\\core.a" "-LC:\\Users\\Igor\\AppData\\Local\\arduino\\sketches\\F960B7B623F068E480A31C4963CA01B2" -lm
C:\Users\Igor\AppData\Local\Temp\cciw4VG9.ltrans0.ltrans.o:(.rodata+0x6): undefined reference to `Print::write(unsigned char const*, unsigned int)'
c:/users/igor/appdata/local/arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/../lib/gcc/avr/7.3.0/../../../../avr/lib/avr5/crtatmega328p.o:(.init9+0x0): undefined reference to `main'
collect2.exe: error: ld returned 1 exit status
exit status 1

Compilation error: exit status 1

Значит узкое место не там.

Откомпилируйте себе какой-нибудь примерчик с опцией -S.

Допустим, у вас написан какой-то такой код, для измерения скорости умножения:

uint32_t measure_mult_speed() {
  float24_t a, b, c;
  uint32_t timestamp = millis();
  for(int i = 0; i < 1000; i++) {
    c = a * b;
    b = c * a;
    a = c * b;
  }
  return millis() - timestamp;
}

Суньте в него две вставки ассемблерные. Они пригодятся потом, чтобы найти нужное место:

uint32_t measure_mult_speed() {
  float24_t a, b, c;
  uint32_t timestamp = millis();
  for(int i = 0; i < 1000; i++) {
    asm("nop\r\nnop\r\nnop");
    c = a * b;
    b = c * a;
    a = c * b;
    asm("nop\r\nnop\r\nnop");
  }
  return millis() - timestamp;
}

И скомпилируйте с опцией -S, чтобы получить ассемблерный листинг. Найдите свои три подряд идущих нопа - это будет интересующее вас место. И сравните то, что нагенерировал компилятор в вашем случае и в случае, когда float24_t заменен на просто float.

И тащите сюда, будем разбираться, почему скорость такая же. Я ставлю на избыточную вложенность функций. Каждый вызов функции - это: положить в стек this. положить в стек аргументы. вызвать функцию\метод. вернуться из функции. Минимум 5 тактов, если считать, что каждое действие занимает 1 такт (что неправда и дела хуже).

Интересно. А с -O2 ?

В формате с фиксированной точкой не представить коэффициенты модели

float kff[3][3] = { { 9.9237E-13, -1.2702E-09, 3.6321E-07 },
                    { -7.9330E-10, 3.7138E-06, 8.3755E-03 },
                    { 1.7514E-07, -8.0434E-04, -7.9905E-01 } };

А для простых вычислений формат с фиксированной точкой удобный. Хотя я просто обычно на 10, 100 или 1000 умножаю число и работаю с ним как с целым, подразумевая, что там еще точка есть.

1 лайк

А пришлите ваш тест, пожалуйста.

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

У меня нет АВР, у меня есть ЕСП32, но мне просто интересно глянуть, во что компилируется ваш код с классами.

С -O2 собрался. Результат в 6! раз быстрее. Что-то тут не так. Не может быть такого…

nP = 215
nT = 700

duration: 12111 usec
Press = 0.99798

duration: 2222 usec
Press24 = 0.99799
1 лайк
Вот в этом посте финальная версия класса и тест для нее

Реализация типа float24_t - #35 от пользователя Goshman

Может может. -O2 - это стандартная оптимизация. А -Os это, типа, для ущербных процессоров, где важнее размер, чем скорость.

А еще это значит, что в class Print - ошибка. Кто-то намудрил из авторов с inline :0). Зуб даю.

Я правильно понимаю, что если выдернуть из ассемблерного листинга нужные куски кода и встроить их в класс, то будет работать быстрее и с опцией -Os? Или компилятор оптимизирует и ассемблерные вставки?

Вы бы для начала сгенерили их и выложили сюда, как @vvb333007 просил - а потом посмотрим, что там

Безотносительно ассемблера, обратите внимание на количество вызывов функций:

// обычный float. К сожалению, ESP32 _поддерживает_ аппаратно float, поэтому код ниже, конечно, быстрее
// и для прямого сравнения не годится. Но сравнивать мы будем не это, а количество вызовов функций:

   9: 001382                l16ui a8, a3, 0
   c: da0800                ufloat.s  f0, a8, 0
   f: 001282                l16ui a8, a2, 0
  12: 2a4000                mul.s f4, f0, f0
  15: da1800                ufloat.s  f1, a8, 0
  18: 000081                l32r  a8, fffc0018 <_Z17calculatePressureRKtS0_+0xfffc0018>
  1b: 2a5110                mul.s f5, f1, f1
  1e: 010823                lsi f2, a8, 4
  21: 000833                lsi f3, a8, 0
  24: 2a2020                mul.s f2, f0, f2
  27: 030863                lsi f6, a8, 12
  2a: 4a2340                madd.s  f2, f3, f4
  2d: 020833                lsi f3, a8, 8
  30: 0a2230                add.s f2, f2, f3
  33: 040833                lsi f3, a8, 16
  36: 2a3030                mul.s f3, f0, f3
  39: 4a3640                madd.s  f3, f6, f4
  3c: 050863                lsi f6, a8, 20
  3f: 0a3360                add.s f3, f3, f6
  42: 070863                lsi f6, a8, 28
  45: 2a0060                mul.s f0, f0, f6
  48: 060863                lsi f6, a8, 24
  4b: 2a1130                mul.s f1, f1, f3
  4e: 4a0640                madd.s  f0, f6, f4
  51: 080843                lsi f4, a8, 32
  54: 4a1520                madd.s  f1, f5, f2
  57: 0a0040                add.s f0, f0, f4
  5a: 0a0100                add.s f0, f1, f0
  5d: 034103                ssi f0, a1, 12

// А вот, что нагенерировал компилятор с -Os, на float24:

   a: 001382                l16ui a8, a3, 0
   d: 24c1a2                addi  a10, a1, 36
  10: da0800                ufloat.s  f0, a8, 0
  13: fab040                rfr a11, f0
  16: 000081                l32r  a8, this->calculatePressure24 + 0xfffc0018>
  19: 0008e0                callx8  a8   // <------------ вызов метода

  1c: 121152                l16ui a5, a1, 36
  1f: 260142                l8ui  a4, a1, 38
  22: 05cd                  mov.n a12, a5
  24: 04dd                  mov.n a13, a4
  26: 04bd                  mov.n a11, a4
  28: 20a550                or  a10, a5, a5
  2b: 000081                l32r  a8, fffc002c <_Z19calculatePressure24RKtS0_+0xfffc002c>
  2e: 0008e0                callx8  a8       // <------------ вызов метода

  31: 001282                l16ui a8, a2, 0
  34: a1a9                  s32i.n  a10, a1, 40
  36: da0800                ufloat.s  f0, a8, 0
  39: 2cc1a2                addi  a10, a1, 44
  3c: fab040                rfr a11, f0
  3f: 000081                l32r  a8, fffc0040 <_Z19calculatePressure24RKtS0_+0xfffc0040>
  42: 0008e0                callx8  a8       // <------------ вызов метода

  45: 1611f2                l16ui a15, a1, 44
  48: 2e01e2                l8ui  a14, a1, 46
  4b: 0fcd                  mov.n a12, a15
  4d: 0edd                  mov.n a13, a14
  4f: 0ebd                  mov.n a11, a14
  51: 0fad                  mov.n a10, a15
  53: 71e9                  s32i.n  a14, a1, 28
  55: 61f9                  s32i.n  a15, a1, 24
  57: 000081                l32r  a8, fffc0058 <_Z19calculatePressure24RKtS0_+0xfffc0058>
  5a: 0008e0                callx8  a8    // <------------ вызов метода

  5d: 000071                l32r  a7, fffc0060 <_Z19calculatePressure24RKtS0_+0xfffc0060>
  60: 141132                l16ui a3, a1, 40
  63: 2a0122                l8ui  a2, a1, 42
  66: 0207b2                l8ui  a11, a7, 2
  69: f580a0                extui a8, a10, 16, 16
  6c: c1a9                  s32i.n  a10, a1, 48
  6e: 51a9                  s32i.n  a10, a1, 20
  70: 0017a2                l16ui a10, a7, 0
  73: 02dd                  mov.n a13, a2
  75: 03cd                  mov.n a12, a3
  77: 026182                s32i  a8, a1, 8
  7a: 000081                l32r  a8, fffc007c <_Z19calculatePressure24RKtS0_+0xfffc007c>
  7d: 0008e0                callx8  a8 // <------------ ну, короче..

  80: 0607b2                l8ui  a11, a7, 6
  83: f580a0                extui a8, a10, 16, 16
  86: 0a6d                  mov.n a6, a10
  88: 0217a2                l16ui a10, a7, 4
  8b: 04dd                  mov.n a13, a4
  8d: 05cd                  mov.n a12, a5
  8f: 016182                s32i  a8, a1, 4
  92: 000081                l32r  a8, fffc0094 <_Z19calculatePressure24RKtS0_+0xfffc0094>
  95: 0008e0                callx8  a8

  98: 012182                l32i  a8, a1, 4
  9b: 75d0a0                extui a13, a10, 16, 8
  9e: 74b080                extui a11, a8, 0, 8
  a1: f4c0a0                extui a12, a10, 0, 16
  a4: f4a060                extui a10, a6, 0, 16
  a7: 000081                l32r  a8, fffc00a8 <_Z19calculatePressure24RKtS0_+0xfffc00a8>
  aa: 0008e0                callx8  a8

  ad: 0a07d2                l8ui  a13, a7, 10
  b0: 0417c2                l16ui a12, a7, 8
  b3: 75b0a0                extui a11, a10, 16, 8
  b6: f4a0a0                extui a10, a10, 0, 16
  b9: 000081                l32r  a8, fffc00bc <_Z19calculatePressure24RKtS0_+0xfffc00bc>
  bc: 0008e0                callx8  a8

  bf: f590a0                extui a9, a10, 16, 16
  c2: 0e07b2                l8ui  a11, a7, 14
  c5: d1a9                  s32i.n  a10, a1, 52
  c7: 41a9                  s32i.n  a10, a1, 16
  c9: 0617a2                l16ui a10, a7, 12
  cc: 02dd                  mov.n a13, a2
  ce: 03cd                  mov.n a12, a3
  d0: 036192                s32i  a9, a1, 12
  d3: 000081                l32r  a8, fffc00d4 <_Z19calculatePressure24RKtS0_+0xfffc00d4>
  d6: 0008e0                callx8  a8

  d9: 1207b2                l8ui  a11, a7, 18
  dc: f580a0                extui a8, a10, 16, 16
  df: 0a6d                  mov.n a6, a10
  e1: 0817a2                l16ui a10, a7, 16
  e4: 04dd                  mov.n a13, a4
  e6: 05cd                  mov.n a12, a5
  e8: 1189                  s32i.n  a8, a1, 4
  ea: 000081                l32r  a8, fffc00ec <_Z19calculatePressure24RKtS0_+0xfffc00ec>
  ed: 0008e0                callx8  a8

  f0: 0401b2                l8ui  a11, a1, 4
  f3: 75d0a0                extui a13, a10, 16, 8
  f6: f4c0a0                extui a12, a10, 0, 16
  f9: f4a060                extui a10, a6, 0, 16
  fc: 000081                l32r  a8, fffc00fc <_Z19calculatePressure24RKtS0_+0xfffc00fc>
  ff: 0008e0                callx8  a8

 102: 1607d2                l8ui  a13, a7, 22
 105: 0a17c2                l16ui a12, a7, 20
 108: 75b0a0                extui a11, a10, 16, 8
 10b: f4a0a0                extui a10, a10, 0, 16
 10e: 000081                l32r  a8, fffc0110 <_Z19calculatePressure24RKtS0_+0xfffc0110>
 111: 0008e0                callx8  a8

 114: f580a0                extui a8, a10, 16, 16
 117: 0a6d                  mov.n a6, a10
 119: 1a07b2                l8ui  a11, a7, 26
 11c: e1a9                  s32i.n  a10, a1, 56
 11e: 0c17a2                l16ui a10, a7, 24
 121: 02dd                  mov.n a13, a2
 123: 03cd                  mov.n a12, a3
 125: 1189                  s32i.n  a8, a1, 4
 127: 000081                l32r  a8, fffc0128 <_Z19calculatePressure24RKtS0_+0xfffc0128>
 12a: 0008e0                callx8  a8

 12d: 1e07b2                l8ui  a11, a7, 30
 130: 0a3d                  mov.n a3, a10
 132: f520a0                extui a2, a10, 16, 16
 135: 0e17a2                l16ui a10, a7, 28
 138: 20d440                or  a13, a4, a4
 13b: 20c550                or  a12, a5, a5
 13e: 000081                l32r  a8, fffc0140 <_Z19calculatePressure24RKtS0_+0xfffc0140>
 141: 0008e0                callx8  a8

 144: 75d0a0                extui a13, a10, 16, 8
 147: f4c0a0                extui a12, a10, 0, 16
 14a: 74b020                extui a11, a2, 0, 8
 14d: f4a030                extui a10, a3, 0, 16
 150: 000081                l32r  a8, fffc0150 <_Z19calculatePressure24RKtS0_+0xfffc0150>

// все, я устал отделять callx8 от всей остальной мешанины, там еще около 8 вызовов.


У меня пока не получилось это сделать. Можете подсказать как и куда поставить опцию -S?

А куда вы вставляли -O2 -O3 и прочие? Туда же и добавьте

неа. проблема в количестве вызываемых функций.

когда у вас написано

int func3(int a, int b) {
  a++;
  return a + b;
}

int func2(int a, int b) {
  a++;
  return func3(a,b);
}
int func1(int a, int b) {
  a++;
  return func2(a,b);
}

То компилятор, при включенной опции -Os нагенерить может 3 вызова функций. А вызов функции - это не дешево. Работа со стеком.

А при включенной -O2, умненький компилятор свернет все это до 1 (одного) вызова, заинлайнив одно в другое.

Можно с другой стороны подойти. Найдите, где у вас скомпилированный скетч лежит:

Найдите (ну или пусть подскажет кто с АВР работает) каталог с вашим компилятором. Нам нужен не он, а утилита ???-???-objdump.exe которая там где-то рядом с компилятором лежит.

У меня он находится в

C:\Users\WINDOWS\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2411\bin\

Скопируйте туда .o файл из каталога найденного на шаге 1 :slight_smile: (слева ваш скетч, справа - каталог с компилятором):

Запустите

???-???-objdump -d -S Имя_O_файла > какое_нибудь_имя.s

Получите листинг ассемблерный, с комментариями

А Вы его код запускали? Я что-то не пойму, откуда в примере ТС могут взяться многократные вызовы метода calculatePressure24