leon_n (15.06.2010 06:42 - 16.06.2010 14:44, просмотров: 137) ответил koyodza на ну, и как Вы получили эти такты? Методику уж расскажите
У, как вы меня сразу то))) Не бейте сильно, виноват кое в чем был не прав, но флеш все же работает медленно! Упростил программу, и измерил всё ещё раз более внимательно, была ошибка, команда чтения(LDR) из ОЗУ всего то 1 такт, как и должно, быть, а вот LDR из флеш ещё хуже, получилось 11 тактов!!! Буду рад признать свою ошибку, если все же чего-то не то делаю и не так измеряю!
Да вы правы, в общем, виде производительность это совокупность многих вещей! И многое зависит от компилятора и последовательности выполнения команд, но хотя бы самые распространенные варианты числа циклов выполнения LDR производители могли бы и приводить, тем более что в ARM основная (т.е. 32 битовая) загрузка переменных возможно только через LDR! В моем случае, основным было табличное преобразование, и программа работала почти в 5 раз медленней, чем число команд и только после не понимания, как такое возможно стал заниматься измерениями!
Позволю себе заметить, что IAR, без оптимизации, при любом обращении к портам, в начале загружает адрес порта из таблицы(во флеш), затем также из таблицы адрес загружаемой в порт переменной, и вывод в порт на Си на 100 МГц процессоре выходит медленней чем в 16 Мгц AVR -:) Пришлось писать вывод на ASM!
Методика измерения такая, делаем цикл скажем 0xff00 раз, зажигаем светодиод, еще один цикл гасим светодиод и т.д., измеряем, полученный меандр осциллографом, можно и частотомером, но и осциллограф имеется довольно точный! В начале вычисляем время выполнения простых команд в цикле, без команды LDR, получаем, что все команды кроме условного перехода выполняются за один такт, условный переход за 4 такта, затем добавляем в цикл измеряемую, команду и для надежности измерений ставим за ней несколько NOP, дабы не портить кеш команд перед переходом, но как показал эксперимент, он и так всегда портится при загрузке данных из флеш! Результаты измерений в приведенной процедуре получились следующие!
Без команды LDR цикл LOOP2 выполняется за 12 тактов, с LDR из ОЗУ за 13, с LDR из Порта за 24, с LDR из Флеш за 23, т.е. чтение из флеш требует 11 тактов, а из порта аж 12!
Ещё если кому интересно перемерил последовательно PUSH+POP {R0-R4,LR} выполняются за 15 тактов, а {R0-R12,LR} за 31 такт.
asm( " MOV R4, # 0x0000F000 \n"
" MOV R1, # 0x00004800 \n"
" ADD R4,R4,R1,ROR #16 \n" // R4=0x 4800F000 (PIO6)
" MOV R6, # 0x00 \n" // тут ставим адрес ОЗУ-0x400, Флеш-0x00, портов -0x04000-0x8000
" ADD R6,R1,R6,ROR #16 \n" // Флеш 0x00-0x0003FFFF; ОЗУ 0x4000000-0x4017FFF
" MOV R0, # 0x40 \n"
"loop: MOV R2, # 0x040 \n"
" EOR R0, R0,R2 \n"
" STRB R0,[R4,#0x100] \n" // зажигаем/гасим светодиод (P6/6 нога)
" SUB R2,R2,R2 \n"
" MOV R5, #0x01 \n"
" MOV R1, # 0x0FF00 \n"//загружаем число циклов (просто 0xff00 удобней всего)
"loop2: ADD R2,R2,R5 \n"
" MOV R1,R1 \n"
" MOV R1,R1 \n"
" MOV R1,R1 \n"
" LDR R3,[R6,#0] \n"//В R6 адрес ОЗУ, Флеш, портов, то что измеряем
" MOV R1,R1 \n"
" MOV R1,R1 \n"
" MOV R1,R1 \n"
" CMPS R2,R1 \n"
" BCC loop2 \n"
" B loop \n" );
Всё перепроверил несколько раз! Внимательно прочитав описание, думаю, что все так и должно быть, выходит флеш все же медленный! Кэш команд, при загрузке данных из флеш сбрасывается! И получается, загрузка данных 5 тактов, загрузка кеш команд ещё 5 тактов, но откуда же ещё один такт берется фиг его знает, но он есть и всё тут! Измерения, проводил на частоте ядра 96Мгц, хотя уже поднял до 100 Мгц вроде тоже работает:) Включил только __FPQBC.
Может, всё же кто подскажет, ARM с быстрым доступом к флеш, на будущее, ибо чую на этом может, и не получится цветок каменный. Хотя, учитывая, что из ОЗУ работать можно, еще помучаюсь! Может все же у серии lm3s(TI), время чтения из флеши будет не больше 2 тактов, никто извращениями как я не занимался?:) Может, у кого есть lm3s, можете измерить, пожалуйста!