Перейти к содержанию
    

Несимметрия конечного результата vinavr компилятора

Всем привет.

Такой вопрос. Почему код

  while(pph!=&ph[8])
  {
   *(pph++)=~(*(pph-4));
  },

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

  while(pph!=&ph[8])
  {
   *(pph++)=~(*(pph-4));
  94:    fd 01           movw    r30, r26
  96:    34 97           sbiw    r30, 0x04; 4
  98:    80 81           ld    r24, Z
  9a:    80 95           com    r24
  9c:    8c 93           st    X, r24
  9e:    80 91 71 00     lds    r24, 0x0071
  a2:    80 95           com    r24
  a4:    11 96           adiw    r26, 0x01; 1
  a6:    8c 93           st    X, r24
  a8:    11 97           sbiw    r26, 0x01; 1
  aa:    90 91 72 00     lds    r25, 0x0072
  ae:    89 2f           mov    r24, r25
  b0:    80 95           com    r24
  b2:    12 96           adiw    r26, 0x02; 2
  b4:    8c 93           st    X, r24
  b6:    12 97           sbiw    r26, 0x02; 2
  b8:    80 91 73 00     lds    r24, 0x0073
  bc:    80 95           com    r24
  be:    13 96           adiw    r26, 0x03; 3
  c0:    8c 93           st    X, r24
  }

Казалось бы чего проще, для всех 4-х байт сделать одно и тоже действие: загрузить байт

в регистр, а лучше бы воспользоваться регистровой парой Z, инвертировать и записать в

новое место, указываемое парой Х. Дальше, почему бы не использовать постинкремент Х+

вместо двух команд adiw и st? Может, кто-то знает, как переделать си-код в нечто подобное?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

-Os, gcc 4.7.2

000066a2 <testfn>:
    66a2:       e2 e9           ldi     r30, 0x92    ; 146
    66a4:       f3 e0           ldi     r31, 0x03    ; 3
    66a6:       df 01           movw    r26, r30
    66a8:       14 97           sbiw    r26, 0x04    ; 4
    66aa:       8c 91           ld      r24, X
    66ac:       80 95           com     r24
    66ae:       81 93           st      Z+, r24
    66b0:       83 e0           ldi     r24, 0x03    ; 3
    66b2:       ea 39           cpi     r30, 0x9A    ; 154
    66b4:       f8 07           cpc     r31, r24
    66b6:       b9 f7           brne    .-18         ; 0x66a6 <testfn+0x4>
    66b8:       08 95           ret

 

static unsigned char ph [8];
void
__attribute__ ((used))
testfn(void)
{
unsigned char * pph = ph;
  while(pph!=&ph[8])
  {
   *(pph++)=~(*(pph-4));
  };
}

 

vinavr компилятора

Отвечая на Ваш вопрос... Меня давно удивляла неоптимальность применявшихся конструкций в winavr. В этом году, к счастью, появились компиляторы из более новых версий gcc. winavr (проект с таким именем на соурсфоргеекс) последний рз обновлялся тогда, когда такие оптимизайии для avr не делались - потому для вашей задачи как переделать си-код в нечто подобное используйте компилятор поновее.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Писать на CИ и надеятся что какие то "дяди" должны за Вас выполнить оптимизацию??? наивно!!!

Пишу на асме всегда сам всё оптимизирую и всегда знаю что и за какое время выполняется.

 

Может, кто-то знает, как переделать си-код в нечто подобное?

:biggrin: На ассемблере писать!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Текст, взятый у Геннадия, дает

static unsigned char ph [8];
void
__attribute__ ((used))
testfn(void)
{
 7e:	ec e5	   	ldi	r30, 0x5C; 92
 80:	f0 e0	   	ldi	r31, 0x00; 0
unsigned char * pph = ph;
 while(pph!=&ph[8])
 {
  *(pph++)=~(*(pph-4));
 82:	81 91	   	ld	r24, Z+
 84:	80 95	   	com	r24
 86:	83 83	   	std	Z+3, r24; 0x03
void
__attribute__ ((used))
testfn(void)
{
unsigned char * pph = ph;
 while(pph!=&ph[8])
 88:	80 e0	   	ldi	r24, 0x00; 0
 8a:	e4 36	   	cpi	r30, 0x64; 100
 8c:	f8 07	   	cpc	r31, r24
 8e:	c9 f7	   	brne	.-14	 ; 0x82 <testfn+0x4>
 {
  *(pph++)=~(*(pph-4));
 };
}
 90:	08 95	   	ret

-Os

avr-gcc 4.5.3 линух

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Писать на CИ и надеятся что какие то "дяди" должны за Вас выполнить оптимизацию??? наивно!!!

Пишу на асме всегда сам всё оптимизирую и всегда знаю что и за какое время выполняется.

 

 

:biggrin: На ассемблере писать!

Золотые слова!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, слова золотые, целиком и полностью поддерживаю. Только они никак не отвечают на мой вопрос.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

UPD: даже не два, а три года!

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возьмите Клёновскую сборку, не обязательно крайнюю. Все-таки уже почти два года сабжу...
Или её, или, для win32, отсюда

 

Тот же тест, что выше.

Ubuntu 10.04, avr-gcc v 4.3.4 (т.е. тоже не слишком новая версия) -- код как у 4.5.3 выше.

avr-gcc -Os -S -mmcu=atmega8 testfn.c

testfn:
    ldi r30,lo8(ph-4)
    ldi r31,hi8(ph-4)
    rjmp .L2
.L3:
    ld r24,Z
    com r24
    std Z+4,r24
    adiw r30,1
.L2:
    ldi r24,hi8(ph+4)
    cpi r30,lo8(ph+4)
    cpc r31,r24
    brne .L3
    ret

В той же убунте 4.7.0 (Klen-20110813) и 4.7.1 код как у Геннадия выше.

 

-O2 не отличается от -Os для всех вариантов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или её, или, для win32, отсюда
+1 Использую avr-gcc-4.7.2. Очень доволен. Есть масса вкусностей: LTO, uint24, __flash и много-много другого...

тыц

тыц2

тыц3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

*(pph++)=~(*(pph-4));
  94:    fd 01           movw    r30, r26
  96:    34 97           sbiw    r30, 0x04; 4
  98:    80 81           ld    r24, Z
  9a:    80 95           com    r24
  9c:    8c 93           st    X, r24
  9e:    80 91 71 00     lds    r24, 0x0071
  a2:    80 95           com    r24
  a4:    11 96           adiw    r26, 0x01; 1
  a6:    8c 93           st    X, r24
  a8:    11 97           sbiw    r26, 0x01; 1
  aa:    90 91 72 00     lds  .....

Взять всю эту бурду выкинуть , написать на asm и вставить на место . А компилировать hex уже из asm

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не, лучше прямо в бинарник

А чем лучше? А то я чего-то отстал от жизни.

Для топикстартера. Вы же сами описали алгоритм. вот и напишите его на ассемблере и сделайте втавку. А если у вас не критично время выполнения, так и пусть процессор петляет. Вы думаете это единственное такое место? Не надо заглядывать в коды, работает и ладно. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это я всё могу сделать на асме и сделаю, здесь проблем нет, хотя инлайновый асм в винавре это нечто. Приведенный в первом посте код - это часть прерывания, которая формирует фазы ЖКИ. Скорости там небольшие, но хотелось бы, чтобы все фазы были симметричны по длительности исполнения, иначе возникнет постоянный микроток через ЖК, который в итоге приведёт к разрушению ЖК. Опять же, 3-4 года назад мне здесь же на форуме все уши прожужжали, как хорошо писать на си, я проникся, стал писать, вот результат. Теперь опять призывают писать на асме. Ну, надо быть последовательными, граждане-братцы...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, надо быть последовательными, граждане-братцы...

А Вы не слушайте кого ни попадя! :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...