Tarkus 0 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба Читал heyrick.co.uk, автор - апологет принципа "код - произведение искусства" :) Например, в одну инструкцию: BIC R0, R0, R0, ASR#31 ; IF R0 < 0 THEN R0 = 0 Или еще лучше, таблица из "N" переходов с помощью всего двух инструкций: .swihandler CMP R11, #((endofjumptable - startofjumptable) / 4) ADDCC PC, PC, R11, LSL #2 B error .startofjumptable B swi0 B swi1 ; etc... .endofjumptable Честно говоря, не понял принципа работы второго примера. Кто-нибудь может прояснить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба .swihandler ; На вход R11 - индекс в таблице переходов 0..макс. допустимый индекс CMP R11, #((endofjumptable - startofjumptable) / 4); проверили чтоб R11 < (макс.доп индекс + 1) ADDCC PC, PC, R11, LSL #2; и выполнили переход B error; иначе перешли на обработку ошибки "недопустимый входной параметр" .startofjumptable B swi0 B swi1 ; etc... .endofjumptable Где-то так. Сорри, форматтер кода - полный боян, такшта несколько нечитабельно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба CMP R11, #((endofjumptable - startofjumptable) / 4) ADDCC PC, PC, R11, LSL #2 B error .startofjumptable B swi0 B swi1 ; etc... .endofjumptable Честно говоря, не понял принципа работы второго примера. Кто-нибудь может прояснить? Неужели лень заглянуть в список инструкций ARM? Сравнение для того, чтобы R11 было меньше или равно размера таблицы. Если действительно меньше или равно, то прыгнуть на адрес PC+(4*R11), где PC указывает на "B swi0". В противном случае выполняется "B error". Читал heyrick.co.uk, автор - апологет принципа "код - произведение искусства" :) Этот принцип для досужей потехи хорош, а для профессиональной деятельности крайне вреден. Если так ковыряться в инструкциях, то времени на работу не останется :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба да в этих примерах ничего удивительного нет! а таблицу переходов таким образом любой нромальный компилятор строит! Так что если хотите посмотреть на особености ARM ассемблера, возьмите разные компиляторы: IAR, GCC, RVCT (только свежие) поставьте максимальную оптимизацию по времени, потом по скорости и смотрите листинг увидите много хитрых приемов. Современный ARM компилер трудно обогнать используя ассемблер, особенно при работе с константами - сидеть и вычислять чего куда сдвинуть и счем проксорить... (особенно если вы используете текстовое имя константы, а компилер то знает ее значение...) В общем, очень мало место осталось где стоит применять ASM ( но знать его все равно полезно) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба Современный ARM компилер трудно обогнать используя ассемблер, Это уж точно плюс пицот! Дык не все верят в очевидное :( особенно при работе с константами - сидеть и вычислять чего куда сдвинуть и счем проксорить... (особенно если вы используете текстовое имя константы, а компилер то знает ее значение...) А вот это, простите, не понял. Писанины больше получается - это факт, и выражений всяких поболее надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба А вот это, простите, не понял. Писанины больше получается - это факт, и выражений всяких поболее надо. Например идет простая инициализация переферии. т.е. надо по куче константных адресов записать константы. Причем обычно константы представлены не числами, а символически (например не 0x12300 a ADC_REG_CTRL). Так вот в силу специфики команд ARM не все контсатны можно оптимально загрузить в регистр, но зная их числовые представления и то что до этого было в регистрах можно получать их разными арифметическими и логическими действиями и компилер с этим прекрасно справляется, а вот руками упаришься считать. (типа что бы получиь константу DAC_INIT_1 = 0x48C04 можно (0x1233>>2)+4 а это одна команда для ARM) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarkus 0 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба .swihandler ADDCC PC, PC, R11, LSL #2; и выполнили переход Где-то так. Сорри, форматтер кода - полный боян, такшта несколько нечитабельно Спасибо, действительно все прозрачно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 5 марта, 2009 Опубликовано 5 марта, 2009 · Жалоба Так вот в силу специфики команд ARM не все контсатны можно оптимально загрузить в регистр Да это понятно, обычно Peripheral-Specific макросы в помощь. Правда, я не особо широкого кругозора - дальше GNU AS не интересовался макросредствами для армов, но не сомневаюсь, что у всяких там кейлов с этим все в порядке Спасибо Пожалуйста Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kons 0 8 марта, 2009 Опубликовано 8 марта, 2009 · Жалоба Этот принцип для досужей потехи хорош, а для профессиональной деятельности крайне вреден. Если так ковыряться в инструкциях, то времени на работу не останется :-) Немного не так. Если неохота ковыряться в инструкциях, надо пользоваться C. Например, обсуждаемая здесь инициализация периферии - уж точно не задача для asm. На таких задачах (как и на большинстве прочих), как верно отметил KRS, Современный ARM компилер трудно обогнать используя ассемблер А вот написать какой-нибудь внутренний короткий цикл на asm (фильтр какой-нибудь или демодулятор) - это часто очень даже имеет смысл. И тут уж все средства хороши. Но (по опыту) максимальный эффект в asm-модуле достигается не жонглированияем битами, а оптимизацией доступа к памяти - использованием вместо кучи LDR/STR одной LDMIA/STMIA. Компилятор так не умеет (ну, кроме входа/выхода в процедуру есс-но). Для ядра ARM7TDMI на задачах типа свертки результат подобного подхода очень даже радует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slavka012 0 8 марта, 2009 Опубликовано 8 марта, 2009 · Жалоба Немного не так. Если неохота ковыряться в инструкциях, надо пользоваться C. Например, обсуждаемая здесь инициализация периферии - уж точно не задача для asm. На таких задачах (как и на большинстве прочих), как верно отметил KRS, А вот написать какой-нибудь внутренний короткий цикл на asm (фильтр какой-нибудь или демодулятор) - это часто очень даже имеет смысл. И тут уж все средства хороши. Но (по опыту) максимальный эффект в asm-модуле достигается не жонглированияем битами, а оптимизацией доступа к памяти - использованием вместо кучи LDR/STR одной LDMIA/STMIA. Компилятор так не умеет (ну, кроме входа/выхода в процедуру есс-но). Для ядра ARM7TDMI на задачах типа свертки результат подобного подхода очень даже радует. Грамотный ответ. Оптимизировать инициализацию переферии - оч глупо. Она выполняется один раз. Оптимизировать цикл (на асм, по сравнению с С) думаю можно практически всегда, особенно если он написан на С человеком, который ассемблера в жизни не видел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 8 марта, 2009 Опубликовано 8 марта, 2009 · Жалоба ....если он написан на С человеком, который ассемблера C в жизни не видел. :) так правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 9 марта, 2009 Опубликовано 9 марта, 2009 · Жалоба Оптимизировать цикл (на асм, по сравнению с С) думаю можно практически всегда Зачем оптимизировать всегда? Я хотел донести такую мысль: не нужно оптимизировать, если и без оптимизации хорошо работает. Я думаю, бессмысленная оптимизация уносит слишком большое количество человеко-лет, которые могли бы быть потрачены более эффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 9 марта, 2009 Опубликовано 9 марта, 2009 · Жалоба Почти в каждой современной книге по С/С++ написано о вреде преждевременной оптимизации и выстраивается последовательность: 1. Программирование алгоритма. 2. Отладка алгоритма и его комплексное тестирование. 3. Изучение быстродействия отдельных функций и модулей. 4. Оптимизация (при необходимости) узких мест. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 9 марта, 2009 Опубликовано 9 марта, 2009 · Жалоба 1. Программирование алгоритма. 2. Отладка алгоритма и его комплексное тестирование. 3. Изучение быстродействия отдельных функций и модулей. 4. Оптимизация (при необходимости) узких мест. Это квадратные советы. Они не учитывают задачи портирования, коих большинство, когда об алгоритме уже известно почти все, надо чтобы оно красиво влезло и не мешало жить наращиваемой функциональности. В таких случаях я лично начинаю с проверки и оптимизации именно узких мест. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 9 марта, 2009 Опубликовано 9 марта, 2009 · Жалоба Но (по опыту) максимальный эффект в asm-модуле достигается не жонглированияем битами, а оптимизацией доступа к памяти - использованием вместо кучи LDR/STR одной LDMIA/STMIA. Компилятор так не умеет (ну, кроме входа/выхода в процедуру есс-но). Иногда очень даже умеет! К тому же использование команд LDM STM не уменьшает количество досупов к памяти данных, а только за счет уменьшения инструкций уменьшается количество досупов к программе, а это не всегда приводит к увеличению быстродействия. И команды LDM STM увеличивают время реакции на прерывание, в RVCT есть даже опция на ограничение числа регистров в этой команде. А вы можете привести конкретный пример цикла где действительно стоит использовать асм? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться