Оптимизация на С

Обсуждаем контроллеры компании Atmel.
Ответить
anb
Родился
Сообщения: 15
Зарегистрирован: Сб янв 05, 2008 00:15:51

Оптимизация на С

Сообщение anb »

Ранее программировал на асме, сейчас начал изучать С.
Возникла задача расположить биты в байте в обратном порядке с максимальным быстродействием.
Ранее на асме сделал бы используя сдвиг через флаг переноса и это бы заняло 16 команд (не считая сохранения регистров и загрузки данных в них).
На C сделал следующее:

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

uint8_t inverse(uint8_t c){
   return
      ((c&0x01)<<7)|
      ((c&0x02)<<5)|
      ((c&0x04)<<3)|
      ((c&0x08)<<1)|
      ((c&0x10)>>1)|
      ((c&0x20)>>3)|
      ((c&0x40)>>5)|
      ((c&0x80)>>7);   
}

Откомпилированный код выполняется более чем за 90 команд.
Вопрос к знатокам C, можно ли как то по другому это реализовать чтобы быстрее работало,
а то почти шестикратный проигрыш в скорости выполнения вызывает проблемы.
Среда AVR Studio 5.1, целевой процессор XMega128A1.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Оптимизация на С

Сообщение uk8amk »

1. обращение к таблице с заранее посчитанными данными.
2. ассемблерная вставка если с асмом все так хорошо.
anb
Родился
Сообщения: 15
Зарегистрирован: Сб янв 05, 2008 00:15:51

Re: Оптимизация на С

Сообщение anb »

Идея с таблицей, думаю, подойдет, даже быстрее будет выполнять.
Спасибо.
anb
Родился
Сообщения: 15
Зарегистрирован: Сб янв 05, 2008 00:15:51

Re: Оптимизация на С

Сообщение anb »

Может кому пригодится:

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

uint8_t inverse2(uint8_t c){
  uint8_t tab_i[256]={0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72,
                 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36,
                 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108,
                 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18,
                 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90,
                 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54,
                 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126,
                 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137,
                 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197,
                 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173,
                 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19,
                 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91,
                 219, 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183,
                 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255};
   
   return   tab_i[c];   
}
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Оптимизация на С

Сообщение a_skr »

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

uint8_t inverse(uint8_t a)
{
  uint8_t r=0;
  if(a & 0x80) r |= 0x01;
  if(a & 0x40) r |= 0x02;
  if(a & 0x20) r |= 0x04;
  if(a & 0x10) r |= 0x08;
  if(a & 0x08) r |= 0x10;
  if(a & 0x04) r |= 0x20;
  if(a & 0x02) r |= 0x40;
  if(a & 0x01) r |= 0x80;
  return r;
}

для mega8 с оптимизацией 2 и получилось порядка 16 команд в худшем случае:

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

uint8_t inverse(uint8_t a)
{
  38:   98 2f          mov   r25, r24
  3a:   99 1f          adc   r25, r25
  3c:   99 27          eor   r25, r25
  3e:   99 1f          adc   r25, r25
  uint8_t r=0;
  if(a & 0x80) r |= 0x01;
  if(a & 0x40) r |= 0x02;
  40:   86 fd          sbrc   r24, 6
  42:   92 60          ori   r25, 0x02   ; 2
  if(a & 0x20) r |= 0x04;
  44:   85 fd          sbrc   r24, 5
  46:   94 60          ori   r25, 0x04   ; 4
  if(a & 0x10) r |= 0x08;
  48:   84 fd          sbrc   r24, 4
  4a:   98 60          ori   r25, 0x08   ; 8
  if(a & 0x08) r |= 0x10;
  4c:   83 fd          sbrc   r24, 3
  4e:   90 61          ori   r25, 0x10   ; 16
  if(a & 0x04) r |= 0x20;
  50:   82 fd          sbrc   r24, 2
  52:   90 62          ori   r25, 0x20   ; 32
  if(a & 0x02) r |= 0x40;
  54:   81 fd          sbrc   r24, 1
  56:   90 64          ori   r25, 0x40   ; 64
  if(a & 0x01) r |= 0x80;
  58:   80 fd          sbrc   r24, 0
  5a:   90 68          ori   r25, 0x80   ; 128
  return r;
}
  5c:   89 2f          mov   r24, r25
  5e:   08 95          ret
anb
Родился
Сообщения: 15
Зарегистрирован: Сб янв 05, 2008 00:15:51

Re: Оптимизация на С

Сообщение anb »

Да, мне еще нужно учиться и учиться мыслить на C правильно. :)
Спасибо за идеи, табличный вариант будет все же быстрее,
а при наличии 128к памяти (в данном проекте), выделить 256 байт на хранение таблицы - не проблема.
Ответить

Вернуться в «AVR»