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

DMA в Allwinner V3s - всё так плохо, или я не понял?

Добрый день.

 

Продолжаю осваивать чип Allwinner V3s.  Столкнулся с таким фактом.

 

Нужно сделать переброс "память-память" самым наискорейшим способом, который возможен.  Начал ковырять DMA и обнаружил несколько малоприятных вещей:

 

1) DMA не поддерживает переменные шаги приращения.  Только программирование через дескрипторы.

 

2) Тактовая частота работы DMA всего 200 МГц !!! В сорцах линукса зачем-то для тактовой DMA используют AHB, которая получается делением на 2  частоты ядра: 1200/2 = 600 МГц.

Затем эти 600 МГц делятся ещё на 3 для DMA.  В итоге выходит всего-навсего 200 МГц.

 

Таким DMA полезно делать только   подкачку аудио-данных при воспроизведении или записи звука.  Или ещё что-нибудь свя занное с забором-выводом данных в периферию! Для быстрого коприрования память-память не подходит!

 

А теперь о хорошем!

 

Если копировать с помощью инструкций NEON:

void MEMCPY(u8 *dst,u8 *src,u32 size)
{
 asm volatile(
              "1:                         \n"
              "VLDM %[src]!,{d0-d7}       \n"
              "VSTM %[dst]!,{d0-d7}       \n"
              "SUBS %[size],%[size],#0x40 \n"
              "BGT 1b                     \n"
              : [dst]"+r"(dst), [src]"+r"(src), [size]"+r"(size) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory"
             );
}

 

то скорость получается самая максимальная.  Если битовое поле TEX выставить равным "001", то получим ещё более высокий прирост в скорости (+20 %):

 

//VIDEO MEMORY
i=61;
mmu_tlb_address[i + (dram_base>>20)] =                              (dram_base + (i << 20))   |
									         (0 << 19)    |
										 (0 << 18)    |
										 (0 << 17)    |
										 (0 << 16)    |
										 (0 << 15)    |
										  (1 << 12)    |  //TEX
										 (3 << 10)    |
									         (0 <<  9)    |
										 (15 << 5)    |
										 (0  << 4)    |
										  (0  << 3)    |  //Cache
										  (1  << 2)    |  //Buffer
										 (2  << 0);

 

При этом бит кеширования в дескрипторе приёмника в MMU-таблице должен быть выключен! Если его включить в приемнике, то скорость просядет.

Тоесть:

приемник: TEX=1, C=0, B=1

источник: TEX=0, C=1, B=1

 

При таком раскладе выходит около 8000 FPS при копировании буфера 240 x 160 x 16 бит. (ядро 1200 МГц, память 456 МГц ).

С DMA выходит в 8 раз меньше!

 

Если увеличить частоту DMA в 2,3 раза, то скорость нисколько не увеличивается.

 

Действительно ли с DMA всё так печально, или есть способ его заставить работать быстрее?

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

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


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

8 minutes ago, __inline__ said:

Для быстрого коприрования память-память не подходит!

Практически на любой относительно "толстой" платформе DMA начисто проигрывает по скорости процессору. Так уж мир устроен, так и должно быть.

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


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

1 час назад, aaarrr сказал:

Практически на любой относительно "толстой" платформе DMA начисто проигрывает по скорости процессору.

А не на толстой, разве выигрывает? Тут все дело в частоте проца, если она примерно равна клоку ДМА, то последний однозначно выигрывает, тут же наоборот, вот и проигрыш. Да и ДМА задуман в основном для асинхронной работы с периферией, для видео есть свои ускорители, но толку от них ноль, т.к. недокументированы, вот и есть поле поизвращаться...

1 час назад, __inline__ сказал:

Если копировать с помощью инструкций NEON:

Впросик - а можно с помощью этих инструкций не копировать, а заполнять прямоугольные области константой?

2 часа назад, __inline__ сказал:

С DMA выходит в 8 раз меньше!

Чет выходит на IMX6 ДМА быстрее в 2 раза аллвиннеровского... Странно, на А13 ДМА было быстрее...

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


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

17 minutes ago, mantech said:

Тут все дело в частоте проца, если она примерно равна клоку ДМА, то последний однозначно выигрывает, тут же наоборот, вот и проигрыш.

А ширина шин, кэш, работа коммутаторов - совсем не при делах?

 

18 minutes ago, mantech said:

Впросик - а можно с помощью этих инструкций не копировать, а заполнять прямоугольные области константой?

Можно.

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


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

2 минуты назад, aaarrr сказал:

А ширина шин, кэш,

Шины всегда были периферийные, а кэш в работе с ДМА вообще не понял о чем это...

2 минуты назад, aaarrr сказал:

Можно.

Не подскажете, что за инструкция?

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

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


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

3 minutes ago, mantech said:

Шины всегда были периферийные, а кэш в работе с ДМА вообще не понял о чем это...

Просто дело не в "частоте проца", а в том, что ядро, по понятным причинам, имеет наиболее мощные возможности при работе с памятью.

 

7 minutes ago, mantech said:

Не подскажете, что за инструкция?

Как ни странно, это vst :)

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


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

22 минуты назад, aaarrr сказал:

Как ни странно, это vst :)

Гуглил на тему "Заполнение памяти константой с помощью NEON" - ничего нет, видать не все так просто...

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


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

16 minutes ago, mantech said:

Гуглил на тему "Заполнение памяти константой с помощью NEON" - ничего нет, видать не все так просто...

 

Восклицательный значок убрать в инструкции источника (инкрементор?). Только константа будет длиной разрядности всех регистров (64 байта)

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


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

1 минуту назад, __inline__ сказал:

Восклицательный значок убрать в инструкции источника

Это где VLDM ?

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


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

1 hour ago, mantech said:

Странно, на А13 ДМА было быстрее...

 

Да, на A13 быстрее, чем у V3s!

1 minute ago, mantech said:

Это где VLDM ?

Да. Из-под цикла инструкцию можно вынести.  Только в этом случае всеравно константа будет в памяти, а не как immediate. 

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

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


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

4 минуты назад, __inline__ сказал:

Только константа будет длиной разрядности всех регистров (64 байта)

Это как? Т.е. VLDM считывает по 64 байта и потом VSTM их кладет по новому адресу?

А приращение вычисляется SUBS? Или это просто вычитание..

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

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


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

30 minutes ago, mantech said:

ничего нет, видать не все так просто...

Пожалуй, наоборот: все так просто, что ничего нет. Напишите свою рисовалку на обычном asm'е, а потом добавьте NEON'а по вкусу. Но не думаю, что замена stm на vst даст что-то выдающееся:

 C fill                                               :   2269.1 MB/s (0.1%)
 NEON fill                                            :   2262.7 MB/s
 NEON fill backwards                                  :   2262.7 MB/s
 ARM fill (STRD)                                      :   2260.3 MB/s
 ARM fill (STM with 8 registers)                      :   2270.0 MB/s (0.1%)
 ARM fill (STM with 4 registers)                      :   2268.7 MB/s (0.2%)

Т.е. любой вариант легко и непринужденно упирается в шину памяти.

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


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

4 minutes ago, mantech said:

Это как? Т.е. VLDM считывает по 64 байта и потом VSTM их кладет по новому адресу?

"VLDM %[src]!,{d0-d7}

в область памяти с адреса src записывается содержимое 8-ми 8-байтовых  регистров d0,d1,...,d7 за раз!  Адреса должны быть выровнены на 64 байта и передача кратна 64-м.

Для быстрой очистки экрана подходит

 

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

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


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

4 минуты назад, aaarrr сказал:

Но не думаю, что замена stm на vst даст что-то выдающееся.

Ну тут как бы по 64 байта за транзакцию кидает, почти как в видеопроцессоре. Ну да, в этот момент проц другим не занимается, в отличии от видеопроца, но в некоторых случаях все-равно ждать отрисовки приходится, так что не все так однозначно...

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

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


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

4 minutes ago, mantech said:

Ну тут как бы по 64 байта за транзакцию кидает, почти как в видеопроцессоре. Ну да, в этот момент проц другим не занимается, в отличии от видеопроца, но в некоторых случаях все-равно ждать отрисовки приходится, так что не все так однозначно...

 

А включенный бит буферизации? Он помогает конвееризировать бурсты?

 

Ещё по теме быстрой отрисовки: https://stackoverflow.com/questions/11161237/fast-arm-neon-memcpy

 

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

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


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

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

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

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

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

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

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

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

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

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