Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

WiseLord писал(а):Архитектура 16-битная, и сдвиг 23-битного (а по сути, 32-битного) числа будет "дороже" чем 16-битного.
Добавляется всего лишь одна команда ассемблера типа RLC A; Да и тут у всех сдвиги так то)
VladislavS писал(а):контроллер 16-битный, сложение и вычитание, скорее всего, будут дорогими.
Вычитание тут грубо говоря 16 битное...старшая часть не трогается. Ну тут как компилятор надумает :))
И чет я прогнал похоже:

f=0x1000;
b=((a<<1)-(a&0x0fff))|f;
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Psych",url="/forum/viewtopic.php?p=4207584#p4207584"]Да и тут у всех сдвиги так то)[/uquote]Точно так же один сдвиг. Разница только в том как младшие 16 бит выводятся. Плюс-минус такт надо в железе проверять.

[uquote="Psych",url="/forum/viewtopic.php?p=4207584#p4207584"]Вычитание тут грубо говоря 16 битное...старшая часть не трогается. Ну тут как компилятор надумает :))[/uquote]Я бы не стал на это надеяться и помог ему.

Код: Выделить всё

((a<<1)&0xFFFF'0000) | (((a<<1)&0x0000'FFFF)-(a&0x7FF)) | (f?(1L<<11):0);
То же самое, возможно, надо сделать и в "тупом варианте" - без листинга компилятора можно только гадать.
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Ну а как же битовые поля?
Спойлер

Код: Выделить всё

union BytByte {
struct {
 uint16_t bl: 11;
 uint16_t bh: 12;
} bit;
uint32_t byte;
}__attribute__((packed));

union BytByte_f {
struct {
 uint16_t bl: 11;
 unsigned bf:1;
 uint16_t bh: 12;
} bit;
uint32_t byte;
}__attribute__((packed));


uint32_t kon_f (uint32_t a, bool f) {
union BytByte myBByte;
union BytByte_f myBByte_f;

	myBByte.byte = a;
	myBByte_f.bit.bl = myBByte.bit.bl;
	myBByte_f.bit.bh = myBByte.bit.bh;		
	myBByte_f.bit.bf = f;

	return myBByte_f.byte;
}
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Dimon456, во-первых, скомпилируй это и посмотри что получится, чисто поржать. Во-вторых, это "индейцезависимый" код, как мне видится.
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS, на чем скомпилировать, есть avr-gcc, arm-gcc, iar?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Да пофиг, для поржать любой пойдёт.
Реклама
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

Dimon456 писал(а):Ну а как же битовые поля?
Gudd-Head писал(а):Необходимо максимально быстро преобразовать 23-х разрядное число в 24-х рязрядное перед выводом в порт путём вставки "1"
Чет сомнения по поводу быстро и битовые поля.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

максимально быстро - это сделать ассемблерную вставку :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ARV",url="/forum/viewtopic.php?p=4207721#p4207721"]максимально быстро - это сделать ассемблерную вставку :)))[/uquote]Не факт. Сквозь ассемблерные вставки оптимизация может не очень работать.

[uquote="Psych",url="/forum/viewtopic.php?p=4207717#p4207717"]Чет сомнения по поводу быстро и битовые поля.[/uquote]+1. Надеюсь, сейчас скомпилирует и сделает свой "фирменный" тест :)

Если то что надо вставить константно, то шаблон поможет оптимизировать и заинлайнить.

Код: Выделить всё

template <bool f>
uint32_t foo(uint32_t a)
{
  return ((a<<1)-(a&0x7FF)) | (f?(1L<<11):0);
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Это большое заблуждение, поверь.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):Надеюсь, сейчас скомпилирует и сделает свой "фирменный" тест
А как же без этого, avr-gcc Атмега8 1МГц -Os.
Если заинлайнить, то мой код выполняется за 70us, ваш код - за 66us, а если не инлайнить, то мой код выполняется за 84us, а ваш - за 150us. Пойдет?
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4207739#p4207739"]Пойдет?[/uquote]Не пойдёт. Я же говорю, тест "фирменный".

ЗЫ: Поясню всё же. Во-первых, под 8-битный процессор надо слегка по другому формулу написать. Во-вторых, никогда не поверю, что на AVR сдвиг 3 байт, и несколько логических операций над одним байтом будет 66 тактов выполняться. В-третьих, оптимизацию по скорости. В-четвёртых, вызов одной функции 14 тактов, а другой с той же сигнатурой 84? Ну-ну. В-пятых, что и как ты измеряешь мы уже проходили.

Добавлено after 1 hour 12 minutes 50 seconds:
Для AVR взял самый тяжёлый вариант, когда всё неконстантно и volatile. Навскидку - 32 такта с загрузкой из памяти и выгрузкой обратно. В реальной программе будет меньше.
Спойлер

Код: Выделить всё

#include "stdint.h"

uint32_t foo(uint32_t a, bool f)
{
  return ((a&0x7FF800)<<1) | (f?(1L<<11):0) | (a&0x7FF);
}

int main()
{
  volatile uint32_t a=0x00123456;
  volatile bool f = false;
  volatile uint32_t y=foo(a,f);  

  return 0;
}
Листинг

Код: Выделить всё

//int main()
main:
//{
        MOV     R19, R25
        SBIW    R29:R28, 5
//volatile uint32_t a=0x00123456;
        LDI     R16, 86
        STD     Y+1, R16
        LDI     R16, 52
        STD     Y+2, R16
        LDI     R16, 18
        STD     Y+3, R16
        LDI     R16, 0
        STD     Y+4, R16
//volatile bool f = true;
        LDI     R16, 1
        ST      Y, R16
//volatile uint32_t y=foo(a,f);    
        LD      R20, Y        // От сих
        LDD     R16, Y+1
        LDD     R17, Y+2
        LDD     R22, Y+3
        LDD     R23, Y+4
        TST     R20
        BREQ    ??main_0
        LDI     R25, 8
        RJMP    ??main_1
??main_0:
        LDI     R25, 0
??main_1:
        MOVW    R21:R20, R17:R16
        LSL     R20
        ROL     R21
        ROL     R22
        LDI     R23, 0
        ANDI    R21, 0xF0
        OR      R21, R25
        ANDI    R17, 0x07
        OR      R21, R17
        ST      Y, R16
        STD     Y+1, R21
        STD     Y+2, R22
        STD     Y+3, R23  // До сих
// 
//  return 0;
        LDI     R16, 0
        LDI     R17, 0
        ADIW    R29:R28, 5
        MOV     R25, R19
        RET
//}
Добавлено after 5 minutes 38 seconds:
Для ARM:
Спойлер

Код: Выделить всё

//GPIOA->IDR = foo<1>(GPIOA->IDR);  // Вставка "1"
        LDR.N    R0,??DataTable1        // Load GPIOA
        LDR      R1,[R0, #+0]           // Read IDR
        UBFX     R2,R1,#+0,#+11         // 1
        RSB      R2,R2,R1, LSL #+1      // 2
        ORR      R2,R2,#0x800           // 3
        STR      R2,[R0, #+0]           // Write IDR
        
//GPIOA->IDR = foo<0>(GPIOA->IDR);  // Вставка "0"
        LDR.N    R0,??DataTable1       // Load GPIOA
        LDR      R1,[R0, #+0]          // Read IDR
        UBFX     R2,R1,#+0,#+11        // 1
        RSB      R2,R2,R1, LSL #+1     // 2
        STR      R2,[R0, #+0]          // Write IDR
16-битного компилятора, извиняйте, нет.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):Для AVR взял самый тяжёлый вариант,
Нашел чем хвалиться, кажется мы эту тему уже проходили.
Ты вот так покажи листинг

Код: Выделить всё

   while (1)
     {
		y=foo(a,f);
		a++;
	}
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Да что же это такое? :( Ежу понятно, что операция a++ на volatile uint32_t будет дополнительных 20 тактов выполняться.

Код: Выделить всё

//a++;
        LDD     R16, Y+1
        LDD     R17, Y+2
        LDD     R18, Y+3
        LDD     R19, Y+4
        SUBI    R16, 255
        SBCI    R17, 255
        SBCI    R18, 255
        SBCI    R19, 255
        STD     Y+1, R16
        STD     Y+2, R17
        STD     Y+3, R18
        STD     Y+4, R19
Только какое отношение это имеет к foo? В жизни, как я и писал, будет вот так. И выполняться весь цикл будет за 29 тактов из которых a++ и переход цикла 5 тактов.

Код: Выделить всё

int main()
{
  uint32_t a=0x00123456;
  volatile bool f = true;
  volatile uint32_t y; 

  while(1)
  {
    y=foo(a,f); 
    a++;
  }  
}
Спойлер

Код: Выделить всё

//int main()
//{
        MOV     R23, R27
        MOV     R0, R26
        MOV     R19, R25
        MOV     R22, R24
        SBIW    R29:R28, 5
//  uint32_t a=0x00123456;
        LDI     R16, 86
        LDI     R17, 52
        LDI     R18, 18
//  volatile bool f = true;
        LDI     R20, 1
        ST      Y, R20
        RJMP    ??main_0
//  volatile uint32_t y; 

//  while(1)
//  {
//    y=foo(a,f); 
??main_1:
        LDI     R21, 0
??main_2:
        MOVW    R25:R24, R17:R16
        MOV     R26, R18
        LSL     R24
        ROL     R25
        ROL     R26
        LDI     R27, 0
        ANDI    R25, 0xF0
        OR      R25, R21
        MOV     R21, R17
        ANDI    R21, 0x07
        OR      R25, R21
        STD     Y+1, R16
        STD     Y+2, R25
        STD     Y+3, R26
        STD     Y+4, R27
//    a++;
        SUBI    R16, 255
        SBCI    R17, 255
        SBCI    R18, 255
??main_0:
        LD      R20, Y
        TST     R20
        BREQ    ??main_1
        LDI     R21, 8
        RJMP    ??main_2
//  }  
//}
А скорее всего вообще вот так за 24 такта из которых a++ и переход цикла 5 тактов.

Код: Выделить всё

int main()
{
  uint32_t a=0x00123456;
  volatile uint32_t y; 

  while(1)
  {
    y=foo(a,1); 
    a++;
  }  
}
Спойлер

Код: Выделить всё

//int main()
//{
        MOV     R23, R25
        SBIW    R29:R28, 4
//  uint32_t a=0x00123456;
        LDI     R20, 86
        LDI     R21, 52
        LDI     R22, 18
//  volatile uint32_t y; 

//  while(1)
//  {
//    y=foo(a,1); 
??main_0:
        MOVW    R17:R16, R21:R20
        MOV     R18, R22
        LSL     R16
        ROL     R17
        ROL     R18
        LDI     R19, 0
        ANDI    R17, 0xF0
        MOV     R25, R21
        ANDI    R25, 0x07
        OR      R17, R25
        ORI     R17, 0x08
        ST      Y, R20
        STD     Y+1, R17
        STD     Y+2, R18
        STD     Y+3, R19
//    a++;
        SUBI    R20, 255
        SBCI    R21, 255
        SBCI    R22, 255
        RJMP    ??main_0
//  }  
//}
 
А со вставкой нуля ещё на такт меньше.

Да уж... Тесты так тесты.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Это на чем? На iar?
и y=foo(a,1); 1 - не может быть константой, это ты уже сокращаешь код.
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4207832#p4207832"]Это на чем? На iar?[/uquote]Да.

[uquote="Dimon456",url="/forum/viewtopic.php?p=4207832#p4207832"]и y=foo(a,1); 1 - не может быть константой,[/uquote]А чем же оно ещё тут является как не константой? Вполне реальный сценарий использования.

[uquote="Dimon456",url="/forum/viewtopic.php?p=4207832#p4207832"]это ты уже сокращаешь код.[/uquote]Литстинги 100% работа компилятора. Я лишь показал разные сценарии применения foo от самого тяжёлого до простого (на самом деле ещё и y может быть не volatile, но это скорее экзотика). Как будет в реальной программе понять можно.

Так что, тренируйтесь на кошечках :)
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

У нас вот какие кошки
СпойлерИзображение
К стати насчет iar, перенес свой проект с arm-gcc на iar и вот какие кошки
Спойлер

Код: Выделить всё

Program Size:
      text	   data	    bss	    dec	    hex	filename
     21685	    144	    808	  22637	   586d	Proekt_32F030.elf

Код: Выделить всё

  14'784 bytes of readonly  code memory
   1'718 bytes of readonly  data memory
   1'864 bytes of readwrite data memory
В проекте используется всего одна библиотечная функция sprintf, больше ни чего библиотечного не используется, остальное мая писанина.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS, ты вот так мог выложить для сравнения
Спойлер

Код: Выделить всё

      8          #include "stdint.h"
      9          
     10          #pragma inline = forced          //Force inline
     11          uint32_t foo(uint32_t a, bool f)
     12          {
     13            return ((a&0x7FF800)<<1) | (f?(1L<<11):0) | (a&0x7FF);
     14          }
     15          
     16          

   \                                 In  segment CODE, align 2, keep-with-next
     17          int main()
   \                     main:
     18          {  
   \   00000000   ....               RCALL   ?PROLOGUE4_L09
   \   00000002   50C5               SUBI    R28, 5
     19            uint32_t a=0x00123456;
   \   00000004   E506               LDI     R16, 86
   \   00000006   E314               LDI     R17, 52
   \   00000008   E122               LDI     R18, 18
     20            volatile bool f = true;
   \   0000000A   E041               LDI     R20, 1
   \   0000000C   8348               ST      Y, R20
   \   0000000E   C013               RJMP    ??main_0
     21            volatile uint32_t y; 
     22          
     23              while(1)
     24            {
     25              y=foo(a,f);
   \                     ??main_1:
   \   00000010   E050               LDI     R21, 0
   \                     ??main_2:
   \   00000012   2F91               MOV     R25, R17
   \   00000014   2FA2               MOV     R26, R18
   \   00000016   E0B0               LDI     R27, 0
   \   00000018   7F98               ANDI    R25, 0xF8
   \   0000001A   77AF               ANDI    R26, 0x7F
   \   0000001C   0F99               LSL     R25
   \   0000001E   1FAA               ROL     R26
   \   00000020   2B95               OR      R25, R21
   \   00000022   2F51               MOV     R21, R17
   \   00000024   7057               ANDI    R21, 0x07
   \   00000026   2B95               OR      R25, R21
   \   00000028   8309               STD     Y+1, R16
   \   0000002A   839A               STD     Y+2, R25
   \   0000002C   83AB               STD     Y+3, R26
   \   0000002E   83BC               STD     Y+4, R27
     26              a++;
   \   00000030   5F0F               SUBI    R16, 255
   \   00000032   4F1F               SBCI    R17, 255
   \   00000034   4F2F               SBCI    R18, 255
   \                     ??main_0:
   \   00000036   8148               LD      R20, Y
   \   00000038   2344               TST     R20
   \   0000003A   F351               BREQ    ??main_1
   \   0000003C   E058               LDI     R21, 8
   \   0000003E   CFE9               RJMP    ??main_2
     27            }
     28          }

   Maximum stack usage in bytes:

     Function CSTACK RSTACK
     -------- ------ ------
     main         9      2


   Segment part sizes:

     Function/Label Bytes
     -------------- -----
     main             64

 
 64 bytes in segment CODE
 
 64 bytes of CODE memory

Код: Выделить всё

      6          #include "stdint.h"
      7          
      8          union BytByte {
      9          struct {
     10           uint16_t bl: 11;
     11           uint16_t bh: 12;
     12          } bit;
     13          uint32_t byte;
     14          };
     15          
     16          union BytByte_f {
     17          struct {
     18           uint16_t bl: 11;
     19           unsigned bs:1;
     20           uint16_t bh: 12;
     21          } bit;
     22          uint32_t byte;
     23          };
     24          
     25          #pragma inline = forced          //Force inline
     26          uint32_t kon_f (uint32_t a, bool f) {
     27          union BytByte myBByte;
     28          union BytByte_f myBByte_f;
     29          
     30          			myBByte.byte = a;
     31          
     32          			myBByte_f.bit.bl = myBByte.bit.bl;
     33          
     34          			myBByte_f.bit.bh = myBByte.bit.bh;
     35          			
     36          			myBByte_f.bit.bs = f;
     37          
     38          	return myBByte_f.byte;
     39          }
     40          
     41          

   \                                 In  segment CODE, align 2, keep-with-next
     42          int main()
   \                     main:
     43          { 
   \   00000000   2F59               MOV     R21, R25
   \   00000002   50C9               SUBI    R28, 9
     44            uint32_t a=0x00123456;
   \   00000004   E506               LDI     R16, 86
   \   00000006   E314               LDI     R17, 52
   \   00000008   E122               LDI     R18, 18
   \   0000000A   E030               LDI     R19, 0
     45            volatile bool f = true;
   \   0000000C   E041               LDI     R20, 1
   \   0000000E   8348               ST      Y, R20
     46            volatile uint32_t y; 
     47          
     48              while(1)
     49            {
     50              y=kon_f(a,f);
   \                     ??main_0:
   \   00000010   8008               LD      R0, Y
   \   00000012   2F73               MOV     R23, R19
   \   00000014   819A               LDD     R25, Y+2
   \   00000016   7F98               ANDI    R25, 0xF8
   \   00000018   2FF1               MOV     R31, R17
   \   0000001A   70F7               ANDI    R31, 0x07
   \   0000001C   2B9F               OR      R25, R31
   \   0000001E   8309               STD     Y+1, R16
   \   00000020   839A               STD     Y+2, R25
   \   00000022   819C               LDD     R25, Y+4
   \   00000024   7F90               ANDI    R25, 0xF0
   \   00000026   707F               ANDI    R23, 0x0F
   \   00000028   2B97               OR      R25, R23
   \   0000002A   832B               STD     Y+3, R18
   \   0000002C   839C               STD     Y+4, R25
   \   0000002E   FA00               BST     R0, 0
   \   00000030   817A               LDD     R23, Y+2
   \   00000032   F973               BLD     R23, 3
   \   00000034   837A               STD     Y+2, R23
   \   00000036   830D               STD     Y+5, R16
   \   00000038   837E               STD     Y+6, R23
   \   0000003A   832F               STD     Y+7, R18
   \   0000003C   8798               STD     Y+8, R25
     51              a++;
   \   0000003E   5F0F               SUBI    R16, 255
   \   00000040   4F1F               SBCI    R17, 255
   \   00000042   4F2F               SBCI    R18, 255
   \   00000044   4F3F               SBCI    R19, 255
   \   00000046   CFE4               RJMP    ??main_0
     52            }
     53          }

   Maximum stack usage in bytes:

     Function CSTACK RSTACK
     -------- ------ ------
     main        11      2


   Segment part sizes:

     Function/Label Bytes
     -------------- -----
     main             72

 
 72 bytes in segment CODE
 
 72 bytes of CODE memory
или вот так?
Спойлер

Код: Выделить всё

      6          #include "stdint.h"
      7          
      8          

   \                                 In  segment CODE, align 2, keep-with-next
      9          uint32_t foo(uint32_t a, bool f)
   \                     foo:
     10          {
   \   00000000   2F79               MOV     R23, R25
     11            return ((a&0x7FF800)<<1) | (f?(1L<<11):0) | (a&0x7FF);
   \   00000002   2344               TST     R20
   \   00000004   F011               BREQ    ??foo_0
   \   00000006   E098               LDI     R25, 8
   \   00000008   C001               RJMP    ??foo_1
   \                     ??foo_0:
   \   0000000A   E090               LDI     R25, 0
   \                     ??foo_1:
   \   0000000C   2F51               MOV     R21, R17
   \   0000000E   2F62               MOV     R22, R18
   \   00000010   E030               LDI     R19, 0
   \   00000012   7F58               ANDI    R21, 0xF8
   \   00000014   776F               ANDI    R22, 0x7F
   \   00000016   0F55               LSL     R21
   \   00000018   1F66               ROL     R22
   \   0000001A   2B59               OR      R21, R25
   \   0000001C   7017               ANDI    R17, 0x07
   \   0000001E   2B15               OR      R17, R21
   \   00000020   2F26               MOV     R18, R22
   \   00000022   2F97               MOV     R25, R23
   \   00000024   9508               RET
     12          }
     13          
     14          
     15          

   \                                 In  segment CODE, align 2, keep-with-next
     16          int main()
   \                     main:
     17          {
   \   00000000   ....               RCALL   ?PROLOGUE4_L09
   \   00000002   50C5               SUBI    R28, 5
     18            
     19            uint32_t a=0x00123456;
   \   00000004   E586               LDI     R24, 86
   \   00000006   E394               LDI     R25, 52
   \   00000008   E1A2               LDI     R26, 18
   \   0000000A   E0B0               LDI     R27, 0
     20            volatile bool f = true;
   \   0000000C   E001               LDI     R16, 1
   \   0000000E   8308               ST      Y, R16
     21            volatile uint32_t y; 
     22          
     23              while(1)
     24            {
     25              y=foo(a,f);
   \                     ??main_0:
   \   00000010   8148               LD      R20, Y
   \   00000012   018C               MOVW    R17:R16, R25:R24
   \   00000014   019D               MOVW    R19:R18, R27:R26
   \   00000016   ....               RCALL   foo
   \   00000018   8309               STD     Y+1, R16
   \   0000001A   831A               STD     Y+2, R17
   \   0000001C   832B               STD     Y+3, R18
   \   0000001E   833C               STD     Y+4, R19
     26              a++;
   \   00000020   5F8F               SUBI    R24, 255
   \   00000022   4F9F               SBCI    R25, 255
   \   00000024   4FAF               SBCI    R26, 255
   \   00000026   4FBF               SBCI    R27, 255
   \   00000028   CFF3               RJMP    ??main_0
     27            }
     28          }

   Maximum stack usage in bytes:

     Function CSTACK RSTACK
     -------- ------ ------
     foo          4      2
     main         9      2
       -> foo     9      2


   Segment part sizes:

     Function/Label Bytes
     -------------- -----
     foo              38
     main             42

 
 80 bytes in segment CODE
 
 80 bytes of CODE memory

Код: Выделить всё

      6          #include "stdint.h"
      7          
      8          union BytByte {
      9          struct {
     10           uint16_t bl: 11;
     11           uint16_t bh: 12;
     12          } bit;
     13          uint32_t byte;
     14          };
     15          
     16          union BytByte_f {
     17          struct {
     18           uint16_t bl: 11;
     19           unsigned bs:1;
     20           uint16_t bh: 12;
     21          } bit;
     22          uint32_t byte;
     23          };
     24          

   \                                 In  segment CODE, align 2, keep-with-next
     25          uint32_t kon_f (uint32_t a, bool f) {
   \                     kon_f:
   \   00000000   50C4               SUBI    R28, 4
     26          union BytByte myBByte;
     27          union BytByte_f myBByte_f;
     28          
     29          			myBByte.byte = a;
   \   00000002   01B9               MOVW    R23:R22, R19:R18
     30          
     31          			myBByte_f.bit.bl = myBByte.bit.bl;
   \   00000004   8139               LDD     R19, Y+1
   \   00000006   7F38               ANDI    R19, 0xF8
   \   00000008   7017               ANDI    R17, 0x07
   \   0000000A   2B31               OR      R19, R17
   \   0000000C   8308               ST      Y, R16
   \   0000000E   8339               STD     Y+1, R19
     32          
     33          			myBByte_f.bit.bh = myBByte.bit.bh;
   \   00000010   811B               LDD     R17, Y+3
   \   00000012   7F10               ANDI    R17, 0xF0
   \   00000014   707F               ANDI    R23, 0x0F
   \   00000016   2B17               OR      R17, R23
   \   00000018   832A               STD     Y+2, R18
   \   0000001A   831B               STD     Y+3, R17
     34          			
     35          			myBByte_f.bit.bs = f;
   \   0000001C   FB40               BST     R20, 0
   \   0000001E   F933               BLD     R19, 3
   \   00000020   8339               STD     Y+1, R19
     36          
     37          	return myBByte_f.byte;
   \   00000022   2F13               MOV     R17, R19
   \   00000024   813B               LDD     R19, Y+3
   \   00000026   5FCC               SUBI    R28, 252
   \   00000028   9508               RET
     38          }
     39          
     40          

   \                                 In  segment CODE, align 2, keep-with-next
     41          int main()
   \                     main:
     42          { 
   \   00000000   ....               RCALL   ?PROLOGUE4_L09
   \   00000002   50C5               SUBI    R28, 5
     43            uint32_t a=0x00123456;
   \   00000004   E586               LDI     R24, 86
   \   00000006   E394               LDI     R25, 52
   \   00000008   E1A2               LDI     R26, 18
   \   0000000A   E0B0               LDI     R27, 0
     44            volatile bool f = true;
   \   0000000C   E001               LDI     R16, 1
   \   0000000E   8308               ST      Y, R16
     45            volatile uint32_t y; 
     46          
     47              while(1)
     48            {
     49              y=kon_f(a,f);
   \                     ??main_0:
   \   00000010   8148               LD      R20, Y
   \   00000012   018C               MOVW    R17:R16, R25:R24
   \   00000014   019D               MOVW    R19:R18, R27:R26
   \   00000016   ....               RCALL   kon_f
   \   00000018   8309               STD     Y+1, R16
   \   0000001A   831A               STD     Y+2, R17
   \   0000001C   832B               STD     Y+3, R18
   \   0000001E   833C               STD     Y+4, R19
     50              a++;
   \   00000020   5F8F               SUBI    R24, 255
   \   00000022   4F9F               SBCI    R25, 255
   \   00000024   4FAF               SBCI    R26, 255
   \   00000026   4FBF               SBCI    R27, 255
   \   00000028   CFF3               RJMP    ??main_0
     51            }
     52          }

   Maximum stack usage in bytes:

     Function   CSTACK RSTACK
     --------   ------ ------
     kon_f          4      2
     main           9      2
       -> kon_f     9      2


   Segment part sizes:

     Function/Label Bytes
     -------------- -----
     kon_f            42
     main             42

 
 84 bytes in segment CODE
 
 84 bytes of CODE memory
ну и мой "фирменный" тест
Спойлер

Код: Выделить всё

1МГц Атмега8
avr-gcc
мой		его
52us	95us	без inline
40us	42us	inline
		
iar
мой		его
47us	37us	без inline
36us	26us	inline
Последний раз редактировалось Dimon456 Вс апр 03, 2022 12:33:16, всего редактировалось 1 раз.
Ответить

Вернуться в «Разные вопросы по МК»