|
Вопрос по быстродействию SAM7 |
|
|
|
Mar 5 2008, 09:28
|
Группа: Новичок
Сообщений: 3
Регистрация: 12-02-07
Пользователь №: 25 262

|
Некоторое время использую в новых проектах AT91SAM7S. Ранее не требовалось оптимизации по быстродействию, но возникла задача, в которой очень важно обеспечить высокую производительность алгоритма. После экспериментов с быстродействием, столкнулся с необъяснимым эффектом. Суть проблемы такова: написал процедуру, просмотрел в дебагере сколько тактов процессора идет на обработку. Зная частоту проца, вычислил время исполнения кода. После практического измерения, реальное время исполнения оказалось значительно выше (примерно в 1.6 раза). Для упрощения задачи написал процедуру: __ramfunc void Benchmark() { volatile unsigned int i ; for ( i = 0 ;(i < 480000 );i++ ) ;
} При частоте ядра 48 МГц время выполнения должно составлять около 100 мс. На практике 160 мс. Частота ядра выставлена верно, измерения фактического времени выполнения тоже верны, все перепроверено несколько раз. Компилятор - IAR, оптимизация отключена. Смотрел асм. Там все верно (должно быть 10 тактов в одном цикле). За счет чего падает производительность. Не понимаю где скрыт подвох.
|
|
|
|
|
Mar 5 2008, 09:51
|

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

|
Цитата(evgene @ Mar 5 2008, 11:28)  За счет чего падает производительность. Не понимаю где скрыт подвох. 1)Может разрешены и исполняются какие-то прерывания от таймера? 2) А почему вы решили, что один проход такого цикла исполняется 10 тактов?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 5 2008, 10:13
|
Группа: Новичок
Сообщений: 3
Регистрация: 12-02-07
Пользователь №: 25 262

|
Цитата(Сергей Борщ @ Mar 5 2008, 19:51)  1)Может разрешены и исполняются какие-то прерывания от таймера? Одно прерывание действительно разрешено, от таймера, (период 1 мс, использую для измерения времени выполнения), но оно, я думаю, увеличивает время исполнения незначительно. Цитата(Сергей Борщ @ Mar 5 2008, 19:51)  2) А почему вы решили, что один проход такого цикла исполняется 10 тактов? Десять тактов я увидел в дебагере, и ещё смотрел асм-листинг. Цитата(aaarrr @ Mar 5 2008, 20:02)  Ума не приложу, из чего там можно сделать 10 тактов. Листинг посмотреть можно? Ниже листинг, у вас 10 тактов не получается, наверное из-за включеной оптимизации. 57 __ramfunc void Benchmark() 58 { \ Benchmark: \ 00000000 04D04DE2 SUB SP,SP,#+4 59 //* Set in Volatile for Optimisation 60 volatile unsigned int i ; 61 //* loop delay 62 for ( i = 0 ;(i < 480000 );i++ ) ; \ 00000004 0010A0E3 MOV R1,#+0 \ 00000008 00108DE5 STR R1,[SP, #+0] \ ??Benchmark_0: \ 0000000C 00009DE5 LDR R0,[SP, #+0] \ 00000010 701AA0E3 MOV R1,#+458752 \ 00000014 531C81E3 ORR R1,R1,#0x5300 \ 00000018 010050E1 CMP R0,R1 \ 0000001C 0300002A BCS ??Benchmark_1 \ 00000020 00109DE5 LDR R1,[SP, #+0] \ 00000024 011091E2 ADDS R1,R1,#+1 \ 00000028 00108DE5 STR R1,[SP, #+0] \ 0000002C F6FFFFEA B ??Benchmark_0 63 64 } \ ??Benchmark_1: \ 00000030 04D08DE2 ADD SP,SP,#+4 ;; stack cleaning \ 00000034 1EFF2FE1 BX LR ;; return Цитата(aaarrr @ Mar 5 2008, 20:02)  Прогнал такой же тест у себя, специально добив цикл nop'ами до 10 тактов - время выполнения ~102мс. Если не жалко, можете скинуть мне ваш проект (ie2@narod.ru). Хочу у себя его прогнать.
|
|
|
|
|
Mar 5 2008, 10:20
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(evgene @ Mar 5 2008, 13:13)  Ниже листинг, у вас 10 тактов не получается, наверное из-за включеной оптимизации. Да нет, у меня RVDS просто. И подумать не мог, что IAR может такой ужас сотворить. Цитата(evgene @ Mar 5 2008, 13:13)  Код ??Benchmark_0: LDR R0,[SP, #+0] MOV R1,#+458752 ORR R1,R1,#0x5300 CMP R0,R1 BCS ??Benchmark_1 LDR R1,[SP, #+0] ADDS R1,R1,#+1 STR R1,[SP, #+0] B ??Benchmark_0 Это не может выполниться за 10 тактов, хоть убейте. Все правильно - ровно 16 тактов на цикл.
|
|
|
|
|
Mar 6 2008, 10:33
|
Местный
  
Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970

|
Цитата(aaarrr @ Mar 6 2008, 14:17)  В результате в R1 получим 0x70000 | 0x5300 = 0x75300 (480000dec). Это просто загрузка константы. Мдя, не осилил сразу. В самом деле ужас. Хотя все равно не понимаю - у меня IAR 4.41 сгенерил вот что на приведенный код : Код \ In segment CODE_I, align 4, keep-with-next 140 __ramfunc void Benchmark() 141 { \ Benchmark: \ 00000000 00B5 PUSH {LR} \ 00000002 81B0 SUB SP,SP,#+4 142 volatile unsigned int i; 143 for ( i = 0;(i < 480000 );i++ ); \ 00000004 0020 MOVS R0,#+0 \ 00000006 0090 STR R0,[SP, #+0] \ ??Benchmark_0: \ 00000008 0098 LDR R0,[SP, #+0] \ 0000000A 0549 LDR R1,??Benchmark_1 ;; 0x75300 \ 0000000C 8842 CMP R0,R1 \ 0000000E 03D2 BCS ??Benchmark_2 \ 00000010 0098 LDR R0,[SP, #+0] \ 00000012 401C ADDS R0,R0,#+1 \ 00000014 0090 STR R0,[SP, #+0] \ 00000016 F7E7 B ??Benchmark_0 144 145 } \ ??Benchmark_2: \ 00000018 01B0 ADD SP,SP,#+4 \ 0000001A 01BC POP {R0} \ 0000001C 0047 BX R0 ;; return \ 0000001E C046 Nop \ ??Benchmark_1: \ 00000020 00530700 DC32 0x75300 Оптимизация отключена
|
|
|
|
|
Mar 6 2008, 12:27
|

Местный
  
Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719

|
Цитата(aaarrr @ Mar 6 2008, 14:39)  Можно. RVDS 2.2, оптимизация отключена: Код Benchmark $a .text 0x00000000: e3a00000 MOV r0,#0 0x00000004: ea000000 B {pc} + 0x8; 0xc 0x00000008: e2800001 ADD r0,r0,#1 0x0000000c: e250c807 SUBS r12,r0,#0x70000 0x00000010: 225ccc53 SUBSCS r12,r12,#0x5300 0x00000014: 3afffffb BCC {pc} - 0xc; 0x8 0x00000018: e12fff1e BX r14 А как же "volatile"? Вот IAR без "volatile". Тоже ничего. Хотя загрузка константы осталась в цикле. Код \ Benchmark: \ 00000000 0010A0E3 MOV R1,#+0 \ 00000004 0100A0E1 MOV R0,R1 \ ??Benchmark_0: \ 00000008 701AA0E3 MOV R1,#+458752 \ 0000000C 531C81E3 ORR R1,R1,#0x5300 \ 00000010 010050E1 CMP R0,R1 \ 00000014 0100002A BCS ??Benchmark_1 \ 00000018 010090E2 ADDS R0,R0,#+1 \ 0000001C F9FFFFEA B ??Benchmark_0 \ ??Benchmark_1: \ 00000020 1EFF2FE1 BX LR ;; return
|
|
|
|
|
Mar 6 2008, 13:09
|

Местный
  
Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719

|
Цитата(Сергей Борщ @ Mar 6 2008, 15:38)  А теперь включите оптимизацию и убедитесь, что цикл исчез вообще  А я и не спорю что исчезнет. Просто в примере от aaarrr я тоже не вижу volatile. Цитата(evgene @ Mar 5 2008, 12:28)  __ramfunc void Benchmark() { volatile unsigned int i ; for ( i = 0 ;(i < 480000 );i++ ) ;
} Не претендую на истину, но правильнее наверно будет так: __ramfunc __arm void Benchmark(){ const int c=480000; volatile unsigned int i ; for ( i = 0 ;(i < c );i++ ); } Соответственно листинг: \ Benchmark: \ 00000000 04D04DE2 SUB SP,SP,#+4 242 const int c=480000; \ 00000004 701AA0E3 MOV R1,#+458752 \ 00000008 531C81E3 ORR R1,R1,#0x5300 \ 0000000C 0100A0E1 MOV R0,R1 243 volatile unsigned int i ; 244 for ( i = 0 ;(i < c );i++ ); \ 00000010 0020A0E3 MOV R2,#+0 \ 00000014 00208DE5 STR R2,[SP, #+0] \ ??Benchmark_0: \ 00000018 00109DE5 LDR R1,[SP, #+0] \ 0000001C 000051E1 CMP R1,R0 \ 00000020 0300002A BCS ??Benchmark_1 \ 00000024 00209DE5 LDR R2,[SP, #+0] \ 00000028 012092E2 ADDS R2,R2,#+1 \ 0000002C 00208DE5 STR R2,[SP, #+0] \ 00000030 F8FFFFEA B ??Benchmark_0 245 } \ ??Benchmark_1: \ 00000034 04D08DE2 ADD SP,SP,#+4 ;; stack cleaning \ 00000038 1EFF2FE1 BX LR ;; return
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|