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

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Ассемблерная оптимизация маленького куска (порядка 10-15 инструкций)
Himmler
сообщение Mar 4 2016, 18:06
Сообщение #31


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 24-06-11
Пользователь №: 65 868



Дело в том, что у меня и так линейный код, без ветвлений, циклов и прочего. Только арифметические операции и загрузка из памяти. Параллелить его не получится, поскольку он идеологически последовательный. Весь параллелизм - это сложить что-нибудь, пока что-то другое загружается из памяти.
Просто судя по времени выполнения, в приведённом мной коде в среднем к каждой команде добавляется ещё и штрафной NOP. Откуда берутся такие задержки - пока не знаю.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 7 2016, 07:45
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Himmler @ Mar 3 2016, 00:16) *
Поглядел на весь код в целом - было бы очень хорошо сэкономить два регистра. Ну или хотя бы один.
Предположительно, это можно как-нибудь сделать, не храня все три адреса в R5, R6 и R7, а храня один их них, а два других -вычисляя на лету. Но тут я столкнулся с тем, что LDRH не хочет делать сдвиги и суммирования, как это делают LDR и LDRB.

Но, судя по системе команд, команда LDRH регистр смещения может как прибавлять к базовому регистру, так и вычитать из базового (если я правильно понимаю описание - не уверен, надо проверить на железе, но не на чем в данный момент).
Так что если в коде
Код
AND R2, R8, R4, LSL #1
AND R3, R8, R4, LSR #11
LDRH R2, [R5, R2]
LDRH R3, [R6, R3]
LDRB R4, [R7, R4, LSR #24]
ADD R2, R2, R3, LSL #12
ADD R2, R2, R4, LSL #24
нулевой индекс таблиц R5 и R6 содержит одинаковое значение, то можно их расположить одна за другой (объединив 0-й индекс) в командах LDRH использовать один базовый регистр, установленный на середину этой объединённой таблицы, и в одной LDRH использовать смещение в '+', а в другой - в '-'. Тогда один регистр сэкономится.

Цитата(Himmler @ Mar 5 2016, 00:06) *
Дело в том, что у меня и так линейный код, без ветвлений, циклов и прочего. Только арифметические операции и загрузка из памяти. Параллелить его не получится, поскольку он идеологически последовательный. Весь параллелизм - это сложить что-нибудь, пока что-то другое загружается из памяти.
Просто судя по времени выполнения, в приведённом мной коде в среднем к каждой команде добавляется ещё и штрафной NOP. Откуда берутся такие задержки - пока не знаю.

Я думаю предлагавший имел в виду разбавить данный кусок кода командами из смежного кода, расположив их в местах предполагаемых "NOP"-ов.
Вам вначале нужно выяснить где именно появляются штрафные такты (эти самые NOPы), чтобы можно было с ними бороться перестановкой и перераспределением инструкций.
Если штрафы накладываются слишком близким расположением точки вычисления адреса/смещения к команде в которой этот адрес используется
(это пары AND R2, R8, R4, LSL #1 / LDRH R3, [R6, R3] и AND R3, R8, R4, LSR #11 / LDRH R3, [R6, R3]) и если штраф - всего один такт, то можно команду LDRB R4, [R7, R4, LSR #24]
сместить на две строчки выше - это уберёт штрафы. Если штрафы больше 1-го такта, то надо этот кусок разбавлять командами из смежного кода.
Go to the top of the page
 
+Quote Post
Himmler
сообщение Mar 7 2016, 07:58
Сообщение #33


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 24-06-11
Пользователь №: 65 868



Ну про перенос команды загрузки я ранее уже писал, это маленько прибавило скорости. А вот про хранение одного адреса на 2 таблицы - не удалось, потому как размер таблиц - 0x2000, а такое значение не влезет в код команды. Изначально у меня была идея разместить таблицы так:
0x3F00 (маленькая таблица на 256 байт)
0x4000
0x6000

При этом хранить только 0x4000, а из него получать сдвигом 0x6000 и вычитанием 0x3F00. Вот только LDRH не позволяет сдвинуть, в отличие от LDR.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 8 2016, 09:37
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Вы не поняли.... sad.gif
Вот описание команды LDRH ядра ARM7TDMI: http://electronix.ru/redirect.php?http://w...arm/lds_str.htm
перемотайте до Рис.25
Нас интересует смещение не в виде константы (рис.26), а в виде регистра (рис.25).
Обратите внимание на бит U.
Так вот: если таблицу, адрес которой находится в R6 записать в обратном порядке и совместить нулевые индексы таблиц R5 и R6 в одном слове, то должно помочь.
Т.е. - при размере таблиц == N элементов будет:
(N-1)-ый индекс таблицы R6
(N-2)-ый индекс таблицы R6
...
(1)-ый индекс таблицы R6
(0)-ой индекс таблиц R5 и R6 (единый)
(1)-ый индекс таблицы R5
...
(N-2)-ый индекс таблицы R5
(N-1)-ый индекс таблицы R5
устанавливаете регистр R5 на адрес (0)-ой индекс таблиц R5 и R6 (единый) и адресуете обе части таблицы командами:
LDRH R2, [R5, R2]
LDRH R3, [R5, -R3]

Освобождается регистр R6.
Go to the top of the page
 
+Quote Post
Himmler
сообщение Mar 8 2016, 09:51
Сообщение #35


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 24-06-11
Пользователь №: 65 868



Точно, неплохая идея. Даже один сэкономленный регистр будет уже в плюс.

Сообщение отредактировал Himmler - Mar 8 2016, 10:01
Go to the top of the page
 
+Quote Post

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

 


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


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