Перейти к содержанию
    

Ассемблерная оптимизация маленького куска (порядка 10-15 инструкций)

Дело в том, что у меня и так линейный код, без ветвлений, циклов и прочего. Только арифметические операции и загрузка из памяти. Параллелить его не получится, поскольку он идеологически последовательный. Весь параллелизм - это сложить что-нибудь, пока что-то другое загружается из памяти.

Просто судя по времени выполнения, в приведённом мной коде в среднем к каждой команде добавляется ещё и штрафной NOP. Откуда берутся такие задержки - пока не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поглядел на весь код в целом - было бы очень хорошо сэкономить два регистра. Ну или хотя бы один.

Предположительно, это можно как-нибудь сделать, не храня все три адреса в 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 использовать смещение в '+', а в другой - в '-'. Тогда один регистр сэкономится.

 

Дело в том, что у меня и так линейный код, без ветвлений, циклов и прочего. Только арифметические операции и загрузка из памяти. Параллелить его не получится, поскольку он идеологически последовательный. Весь параллелизм - это сложить что-нибудь, пока что-то другое загружается из памяти.

Просто судя по времени выполнения, в приведённом мной коде в среднем к каждой команде добавляется ещё и штрафной 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-го такта, то надо этот кусок разбавлять командами из смежного кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

0x3F00 (маленькая таблица на 256 байт)

0x4000

0x6000

 

При этом хранить только 0x4000, а из него получать сдвигом 0x6000 и вычитанием 0x3F00. Вот только LDRH не позволяет сдвинуть, в отличие от LDR.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы не поняли.... :(

Вот описание команды 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Изменено пользователем Himmler

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...