реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Про IAR компилятор С
Dopler
сообщение Feb 6 2007, 14:45
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Здравствуйте.

Раньше никогда на C под железо не писал, только на ассемблере. Но жизнь показывает, что для ARM писать все на asm не актуально. Начал смотреть, какой код генерирует компилятор. Вот для примера две строки на C:

Код
      for(waiting_time = 1999; waiting_time >= 0; waiting_time--);

      for(waiting_time = 0; waiting_time <= 2000; waiting_time++);


Обе эти строки эквивалентны с точки зрения выполнения программы на С (т.е. будет 2000 шагов). Компилятор генерирует следующий код:

\ main:
\ ??main_0:
\ 00000000 CF00A0E3 MOV R0,#+207
\ 00000004 700E80E3 ORR R0,R0,#0x700
\ 00000008 000000EA B ??main_1
\ ??main_2:
\ 0000000C 010040E2 SUB R0,R0,#+1
\ ??main_1:
\ 00000010 000050E3 CMP R0,#+0
\ 00000014 FCFFFF5A BPL ??main_2
19
20 //AT91C_BASE_PIOB->PIO_CODR = 1 << 22;
21 for(waiting_time = 0; waiting_time < 2000; waiting_time++) ;
\ 00000018 0000A0E3 MOV R0,#+0
\ ??main_3:
\ 0000001C 7D0E50E3 CMP R0,#+2000
\ 00000020 F6FFFFAA BGE ??main_0
\ 00000024 010080E2 ADD R0,R0,#+1
\ 00000028 FBFFFFEA B ??main_3



Мне кажется, что выделенная строка явно лишняя, так как флаг нулевого значения выставляется и в предыдущей команде. Во-вторых, при декременте (в первом варианте) есть лишний переход. Таким образом, эквивалентность циклов на С достигнута искуственно. Возможно, это сделано специально (а возможно, человек пока способен генерировать все же лучший код)? Возможно, это где-то описанно или отключается?
Go to the top of the page
 
+Quote Post
Newegor
сообщение Feb 6 2007, 15:08
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 2-03-06
Из: Минск
Пользователь №: 14 879



Поиграйтесь с настройками оптимизации. При различном уровне - будет различный код.
Go to the top of the page
 
+Quote Post
VAI
сообщение Feb 6 2007, 16:58
Сообщение #3


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



я, обычно, смотрю листинг, что у меня получилось, делаю несколько вариантов одного и того-же (как Вы в Вашем примере), и выбираю, с моей точки зрения, оптимальный.
И уровень оптимизации делаю максимальный или приближеный к нему.


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 8 2007, 15:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Забавно, а у меня комилятор в обоих случаях сгенерил одно и то же:
Код
    for (i=0; i<2000; i++)
        __no_operation();
    for (i=1999; i>=0; i--)
        __no_operation();

    for (i=0; i<2000; i++)
  000195C4  E3A00E7D  MOV          R0, #0x7D0
        __no_operation();
  000195C8  E1A00000  NOP          
    for (i=0; i<2000; i++)
  000195CC  E2500001  SUBS         R0, R0, #0x1
    for (i=0; i<2000; i++)
  000195D0  1AFFFFFC  BNE          0x0195C8
    for (i=1999; i>=0; i--)
  000195D4  E3A00E7D  MOV          R0, #0x7D0
        __no_operation();
  000195D8  E1A00000  NOP          
    for (i=1999; i>=0; i--)
  000195DC  E2500001  SUBS         R0, R0, #0x1
    for (i=1999; i>=0; i--)
  000195E0  1AFFFFFC  BNE          0x0195D8


Это IAR 4.40, С++, максимальная оптимизация на скорость. Надо сказать, этот компилятор оставляет хорошее впечатление.
А вообще лучше не лезть в дела компилятора, а заниматься более интересными вещами, то есть написанием программ. Проверять сгенерированный код надо только тогда, когда не хватает памяти или скорости. Иначе не останется времени на отдых :-)
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 8 2007, 16:02
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Цитата(scifi @ Feb 8 2007, 15:26) *


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

Вопрос в том, что при желании сделать например, функцию
Код
SimpleDelay (long d)
{
     for (;d!=0;d--);

}


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

Следующий вопрос, а как-нибудь вообще можно объявить функцию на asm как inline? Или сделать макрос на asm для использования в C-коде?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 8 2007, 17:28
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Dopler @ Feb 8 2007, 15:02) *
Если убрать пустую операцию, то весь цикл попадает под нож оптимизатора при максимальной оптимизации
Если писать правильно, то не попадает.
Цитата(Dopler @ Feb 8 2007, 15:02) *
Вопрос в том, что при желании сделать например, функцию
Код
SimpleDelay (long d)
{
     for (;d!=0;d--);
}

Этот самый Delay будет прямо зависить от режима оптимизации, и вообще улетит при максимальной.
А если так:
Код
SimpleDelay (long volatile d)
{
     for (;d!=0;d--);
}
При разном уровне действительно возможно различное время выполнения, но можно ведь для этой конкретной функции выставить желаемый уровень оптимизации с помощью #pragma.
Цитата(Dopler @ Feb 8 2007, 15:02) *
Следующий вопрос, а как-нибудь вообще можно объявить функцию на asm как inline? Или сделать макрос на asm для использования в C-коде?
В gcc вроде да, в IAR - точно нет. Про остальные не знаю.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 8 2007, 20:49
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата
Следующий вопрос, а как-нибудь вообще можно объявить функцию на asm как inline? Или сделать макрос на asm для использования в C-коде?


Попробуйте так:

#define DELAY(N) __asm("mov R0,#" #N "\nSUBS R0,R0,#1\nBNE .-4");
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 8 2007, 22:21
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Цитата(scifi @ Feb 8 2007, 20:49) *
Попробуйте так:

#define DELAY(N) __asm("mov R0,#" #N "\nSUBS R0,R0,#1\nBNE .-4");



И при использовании такого макроса компилятор гарантированно не будет использовать R0 в своих целях?
Что-то я ничего внятного в документации IAR по поводу INLINE ASSEMBLER не нашел, кроме того, что его лучше избегать.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 8 2007, 22:50
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Dopler @ Feb 8 2007, 21:21) *
И при использовании такого макроса компилятор гарантированно не будет использовать R0 в своих целях?

Не будет sad.gif и много чего другого не будет sad.gif Верный способ угробить оптимизацию sad.gif - посему действительно не стоит использовать такие вставки....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 9 2007, 08:51
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Похоже самый надежный способ, это тот, который рекомендовал Сергей Борщ, это принудительно задавать уровень оптимизации для некоторых функций, используя при этом volatile.

Еще вопрос, как нибудь в IAR можно узнать, за сколько тактов процессора выполнится кусок кода? А то в некоторых случаях это не совсем очевидно (некоторые команды asm заменяются двумя, обнуление конвеера и т.д.)
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 9 2007, 11:37
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Если я правильно понял, нужно получить малые задержки. Предлагаю для этих целей написать функцию на ассемблере и вызывать её из Си. Если пытаться добиться этого при помощи компилятора, то результат будет зависеть от опций компилятора и, возможно, его версии, что не очень приятно (проапгрейдили компилятор - будьте готовы к тому, что старый код перестанет работать).
Время выполнения кода зависит от модели процессора и задержек при доступе к памяти. Для процессора ARM7TDMI времена выполнения инструкций указаны в "ARM7TDMI Technical Reference Manual":
http://www.arm.com/pdfs/DDI0210C_7tdmi_r4p1_trm.pdf (2 MB)
О задержках при доступе к памяти: см. документацию на используемый микроконтроллер.
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 9 2007, 12:36
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Цитата(scifi @ Feb 9 2007, 11:37) *
Если я правильно понял, нужно получить малые задержки. Предлагаю для этих целей написать функцию на ассемблере и вызывать её из Си.


Просто для совсем маленьких функций накладные расходы по вызову и передаче параметров неприятны. Если бы можно было бы функцию на asm сделать inline, было бы здорово.
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 9 2007, 13:02
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Так #pragma optimize не позволяет повысить уровень оптимизации, что это за лажа такая?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 9 2007, 13:13
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(scifi @ Feb 9 2007, 10:37) *
Время выполнения кода зависит от модели процессора и задержек при доступе к памяти. Для процессора ARM7TDMI времена выполнения инструкций указаны в "ARM7TDMI Technical Reference Manual":

И наличия MAM и наличия Кэш и эффективности работы оных а еще DMA захватит шину smile.gif. Короче, лучше навсегда выкиньте из головы желание узнать для более-менее современых контроллеров "точное" время исполнения чего-либо.

Цитата(Dopler @ Feb 9 2007, 12:02) *
Так #pragma optimize не позволяет повысить уровень оптимизации, что это за лажа такая?

Изъясняйтесь конкретнее.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Dopler
сообщение Feb 9 2007, 14:40
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425



Цитата(zltigo @ Feb 9 2007, 13:13) *
Цитата(Dopler @ Feb 9 2007, 12:02) *

Так #pragma optimize не позволяет повысить уровень оптимизации, что это за лажа такая?

Изъясняйтесь конкретнее.


Я имел в виду, что любимой избранной функции нельзя задать жестко уровень оптимизации. Т.е. нельзя написать какую-нибудь простенькую функцию, определить для нее максимальную оптимизацию и наслаждаться, при условии, что остальной проект выполнен без оптимизации.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th June 2025 - 22:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016