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

C6745 CPU vs. DMA, вопрос

Сделал замеры скорости отрисовки кадра на дисплей через DMA и с помощью CPU.

Дисплей: 480x320 16 бит на точку. Интерфейс - параллельная шина 8 бит.  Клок шины 91.2 МГц . Времянки для дисплея на EMIFA такие:

void EMIFA_Init(void)
{
 EMIFA_CE2CFG= (0<<31)| //Select Strobe (0 - Normal Mode)
               (0<<30)| //Extend Wait (0 - disabled)

               (0<<26)| //Write setup width 0..15 (0 - EMA_CLK/1)
               (1<<20)| //Write strobe width 0..63 (0 - EMA_CLK/1)
               (0<<17)| //Write hold width 0..7 (0 - EMA_CLK/1)

               (0<<13)| //Read setup width 0..15 (0 - EMA_CLK/1)
               (1<< 7)| //Read strobe width 0..63 (0 - EMA_CLK/1)
               (0<< 4)| //Read hold width 0..7 (0 - EMA_CLK/1)

               (0<< 2)| //Minimum Turn-Around time (min. num. of EMA_CLK cycles between reads & writes - 1)
                0     ; //Asynchronous Data Bus Width (0 - 8 bit)
}

Тоесть всё на максимуме, кроме Write Strobe Width. Если его укоротить до 0, то изображение начинает "ехать по горизонтали". Поэтому тестировался стабильный вариант.

Ядро на 456 МГц, кеширование L1P, L1D ,L2  включены.  Регионы SDRAM прокешированы. Адрес картинки в SDRAM выровнен на границу 256 бит.

Трансфер идёт с SDRAM в порт LCD_Data.

Дополнительно  выставил максимальный размер бурста:

CFGCHIP0=(2<<2)|2;               //PLL MMRs unlock & TC1 64 byte & TC0 64 byte (DBS)

Если выставить бурст 32 байта - скорость не меняется.  Но если поставить 16 - то скорость немного падает.

 

DMA отрисовывает 74 кадра в секунду.  Это выходит скорость : 320*480*2*74 = 21,68 МБайт/с.

CPU отрисовывает немного меньше - 70 кадров/с.

Код отрисовки - через 64-битный указатель:

void LCD_Picture(u32 o,u32 n) //64 bit transfer
{
 n>>=3;
 register u64 *P=(u64*)&Picture[o];
 while(n--)LCD_D64=*P++;
}

Если отрисовывать через 32- 16- и особенно 8- битные указатели - скорость линейно падает.

Оптимизация компилятора - максимальная "5" по скорости.

Регион портов LCD не кеширован.

 

Кстати,  отключал кеширование в разных комбинациях -  DMA работает с одинаковой скоростью и на кеширование ему начихать.

 

Вопрос собственно вот в чём - возможно ли получить бОльшую скорость отрисовки без изменения аппаратной части ?

Включить Write Buffer для порта LCD или изменить политику кеширования? Или это предел?

Можно ли разогнать EMIFA до 101,3 МГц ? - с такой тактовой скорость отрисовки уже выходит чуть больше.

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


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

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

Код отрисовки - через 64-битный указатель:

Если отрисовывать через 32- 16- и особенно 8- битные указатели - скорость линейно падает.

Имхо - таким кодом Вы не используете все возможности DSP по параллельной обработке. Дело не в разрядности указателей. Почитайте хотя-бы про intrinsic-функции CCS для этого ядра. Вот мой код функции заполнения массива (CCS3.3):

//!Fills an array of u32 values.
//!{dst} - starting address of array; {val} - fill value;
//!{n} - number of values.
//!{dst} - should be aligned to the 8 bytes
//!{n} - should be a multiple of 2.
#pragma CODE_SECTION(".textL2")
void arrayset64p32(void *dst, u32 val, int n)
{
  _nassert((int)dst % 8 == 0);
  _nassert(n % 2 == 0);
  u64 k = _itoll(_ftoi(val), _ftoi(val));
  for (; (n -= 2) >= 0; dst = (void *)((u32 *)dst + 2)) _amem8(dst) = k;
}

Функция копирования блока памяти:

//!Copies array of {n} float values from {src} to {dst}.
//!{src} and {dst} - should be aligned to the 8 bytes
//!{n} - should be not equal to 0 and should be a multiple of 2.
#pragma CODE_SECTION(".textL2")
void SpBlkMove2(float const * restrict src, float * restrict dst, int n)
{
  _nassert((int)dst % 8 == 0);
  _nassert((int)src % 8 == 0);
  _nassert(n > 0 && n % 2 == 0);
  do {
    _amem8((void *)dst) = _amem8((void *)src);
    src += 2;
    dst += 2;
  } while (n -= 2);
}

Для быстрой работы с памятью очень полезно _amem8(). Прочитайте также про модификатор restrict.

И вообще - в CCS есть библиотека с примерами подобных функций (DSPLIB) в исходниках. Откройте посмотрите как правильно это делается.

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


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

Попробовал адаптировать Ваш последний фрагмент кода под свои нужды - приёмник LCD экран, без инкремента адреса:

void LCD_Picture2(float const * restrict src,int n)
{
 float * restrict dst=(float*)0x60004000; //LCD Data Port
 do
 {
  _amem8((void*)dst)=_amem8((void*)src);
  src+=2;
 }
 while(n-=2);
}

Вызов:

LCD_Picture2((float const*)Picture,sizeof(Picture)>>2);

Не работает как надо: экран вместо картинки показывает несколько строк, залитыми серым цветом.

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

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


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

Немного повысил скорость путём изменения режима работы EMIFA, выбран Strobe Mode вместо Normal Mode, тем самым, Write Strobe Width стало возможным укоротить без нарушения работы LCD:

 EMIFA_CE2CFG= (1<<31)| //Select Strobe (0 - Normal Mode)
               (0<<30)| //Extend Wait (0 - disabled)

               (0<<26)| //Write setup width 0..15 (0 - EMA_CLK/1)
               (0<<20)| //Write strobe width 0..63 (0 - EMA_CLK/1)
               (0<<17)| //Write hold width 0..7 (0 - EMA_CLK/1)

               (0<<13)| //Read setup width 0..15 (0 - EMA_CLK/1)
               (0<< 7)| //Read strobe width 0..63 (0 - EMA_CLK/1)
               (0<< 4)| //Read hold width 0..7 (0 - EMA_CLK/1)

               (0<< 2)| //Minimum Turn-Around time (min. num. of EMA_CLK cycles between reads & writes - 1)
                0     ; //Asynchronous Data Bus Width (0 - 8 bit)

Теперь так:

91 кадров в секунду - CPU

98 кадров в секунду - DMA

Режимы(выбран вариант справа):

strobe.thumb.jpg.1018eb8b3eb3e7701877d5528db7504f.jpg

 

А вот тут 60 FPS через SPI и площадь экрана в 2 раза меньше: https://retropie.org.uk/forum/topic/14519/fast-refresh-rates-up-to-60fps-with-an-spi-display-ili9341

 

 

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


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

5 часов назад, __inline__ сказал:

Выкинул RESTRICT - всё заработало,  но число кадров в секунду то же - 70

Вы бы сначала прочитали что это такое и зачем. А не тупо "вставить-убрать"....

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


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

16 hours ago, jcxz said:

Вы бы сначала прочитали что это такое и зачем. А не тупо "вставить-убрать"....

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

 

Пользуясь случаем, как раз на счёт свопинга спрошу,  можно ли в настройках EDMA  указать чтобы байты менялись местами - старший с младшим ?

 

Когда шина дисплея 8 бит, а передача идёт 16- 32-  и 64- разрядными словами,  то DMA передаёт вначале  старший байт, а надо младший! (иначе цвет  точек некорректный)

 

В STM32H743 такая возможность есть.  Есть ли в C6745 ?

 

P.S. при первом наборе постов не сохраняется форматирование, приходится редактировать.  Движок форума можно пофиксить?

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

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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