mantech 32 9 августа, 2019 Опубликовано 9 августа, 2019 (изменено) · Жалоба 19 часов назад, Integro сказал: Если все три бита стоят, значит кеш должен работать, нужно регионы проверять Ну и артифакты на экране вроде как косвенный признак. Кстати они должны быть? В коде еще нет соответвующего менежмента? Еще б знать как... До сих пор не могу найти вменяемое описание этой долбаной таблицы TTB, которая. Досада в том, что на А9 и А8 все работало, как говорится, из коробки, никаких вопросов, тут какой-то гемор возник, может из за 2хядерности, хотя второе ядро не использую... С экраном была такая вещь, еще на А9м, когда с дуру закэшировал экранную область, появились артефакты в виде полосочек в 8 или 16 пикселей, потом понял, что ступил и перевел страницы в режим буфера, после этого все стало норм, тут же, пока D кэш отключен артефактов нет, включаю - появляются, распределение памяти не менял, вообщем х.з.... Вот поле под названием "Section"- похоже на таблицу ММУ, только вот что означают все эти битики?... ЗЫ. Вообщем, методом "научного тыка" таки смог увеличить быстродействие с 200 попугаев до 3500, т.е. больше, чем в 10 раз. Думаю, это заслуга того, что кэш данных заработал, но тут есть несколько странных моментов, которые я понять не могу: 1) Заработало после того, как я поставил в 1 флаг B (buffering) вместе с флагом (С) кэширование. В А8 и А9 этого было делать не нужно. 2) Артефакты в графике - тут вообще странно. В А8 и А9 для ускорения печати текста включил режим буфера для экранной области, проверил на рисовании закрашенного прямоугольника программным способом, На А8 при отключенном буфере 350 усл отсчетов, при включенном - 70, т.е. прирост заметный, затем включил бит кэша, стало 50, т.е. еще быстрее, без артефактов. На А9 другая история, прирост включения буфера был, но не настолько (150 вместо 400), но включение кэша дало артефакты, хоть и ускорило до 100. Что в принципе логично, т.к. экранную область кэшировать не рекомендуется. А на этом А7 при сброшенных битах кэша и буфера, получаю 70 ед. т.е. как-будто буфер уже включен, думал, может там флаг инверсный, но установка его в 1 ничего не дает вообще, установка флага кэша - ускоряет, но артефачит. Вообщем какое-то поле чудес... Изменено 10 августа, 2019 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба On 8/10/2019 at 2:10 AM, mantech said: Что в принципе логично, т.к. экранную область кэшировать не рекомендуется Я бы сказал, что не то что не рекомендуется, а её вообще нельзя кешировать. Так как оптимизатор кеша может сбить всю последовательность передачи данных и команд в дисплей на своё усмотрение. С A7, A9 не работал, но с ядром ARM9 пришлось в своё время повозиться (был вот такой динозавр: AT91RM9200). Ниже код инита MMU лишь только с целью включить Data Cache. Виртуальные адреса совпадают с физическими (мне было так удобнее). Для перифералов (дисплей, синтезаторы звука,...) кеширование не было включено, но был включен некий Bufferable (внятное назначение узнать не удалось, но он давал увеличение быстродействия при отрисовки на дисплей): #define MMUTable (SRAM_Address+0x001FC000) //Базовый адрес First-Level Translation Table, выровнен на границу 16 kB u32 PrepareMMU(void) //Заполняем First-Level Translation Table, бит 3 - Cache, бит 2 - Buffer { *(u32*)(MMUTable+(0x000<<2))=0x00000C1E; //Internal SRAM after ReMap CB *(u32*)(MMUTable+(0x001<<2))=0x00100C1E; //Manufacturer ROM CB *(u32*)(MMUTable+(0x002<<2))=0x00200C16; //Internal SRAM B *(u32*)(MMUTable+(0x100<<2))=0x10000C1E; //External SRAM first MB CB *(u32*)(MMUTable+(0x101<<2))=0x10100C1E; //External SRAM second MB CB *(u32*)(MMUTable+(0x200<<2))=0x20000C16; //FM/WT Synthesizer B *(u32*)(MMUTable+(0x300<<2))=0x30000C16; //MPU401 B *(u32*)(MMUTable+(0x400<<2))=0x40000C16; //OLED B *(u32*)(MMUTable+(0xFFF<<2))=0xFFF00C12; //Internal Peripherals - return MMUTable; } Включение кешей, MMU: ;MMU IMPORT PrepareMMU BL PrepareMMU ;Return First-Level Translation Table Address in R0 ;Write First-Level Translation Table Address MCR p15,0,R0,c2,c0,0 ;Write Domain LDR R0,=0x00000003 MCR p15,0,R0,c3,c0,0 ;Enable ICache, DCache, MMU LDR R0,=0x4000507D MCR p15,0,R0,c1,c0,0 ;Enter the C code IMPORT __main BL __main P.S. Тема интересная, буду следить за дальнейшим её ходом :) Изменено 11 августа, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба Кстати, в современном cmsis включено куча оберток вокруг обращений к cp15. Дисплей тут фреймбуфер обсуждается... ему в общем-то на последовательность всеравно. Главное - чтобы дошло до памяти. А пробовали cleandcachebyaddr или еще как? Изменено 11 августа, 2019 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 августа, 2019 Опубликовано 11 августа, 2019 · Жалоба Еще я сталкивался с тем что перед включением надо вручную кэш инвалидировать. Иначе все что было после ресет вываливается в память... как работает после этого понятно. Кстати в cmsis теперь есть и на эту тему код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба 1 hour ago, GenaSPB said: Кстати, в современном cmsis включено куча оберток вокруг обращений к cp15. Да, есть такое. Сейчас наблюдается нездоровая тенденция скрывать фундаментальные знания. Скоро разучатся писать на Си, не говоря уже об Ассемблере. Зато облака будут и питоны... И призмы, гуглы с ФБР месте взятые и штрих-коды на лбу... Не за горами это будущее. К сожалению. Quote А пробовали cleandcachebyaddr или еще как? Из того что мне нужно было: сбрасывал из кеша в память для ДМА по SPI. (Clean DCache, Flush) Quote Еще я сталкивался с тем что перед включением надо вручную кэш инвалидировать. Иначе все что было после ресет вываливается в память... как работает после этого понятно. Кстати в cmsis теперь есть и на эту тему код. Не сталкивался с таким. На всякий случай добавлю, что тот код выше запускался во внутренней RAM контроллера, изначально кеширование и ММУ были запрещены. Внешняя память - 16-битная SRAM от Cypress на 2 МБ. (Не SDRAM). Проект старенький - 2008 года. Стартап - простой до безобразия: ;Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs Mode_SVC EQU 0x13 Mode_IRQ EQU 0x12 Mode_FIQ EQU 0x11 I_Bit EQU 0x80 ;When I bit is set, IRQ is disabled F_Bit EQU 0x40 ;When F bit is set, FIQ is disabled ;Stack Configuration (Stack Sizes in Bytes) SVC_Stack_Size EQU 0x00000100 IRQ_Stack_Size EQU 0x00000100 FIQ_Stack_Size EQU 0x00000000 Stack_Size EQU (SVC_Stack_Size+IRQ_Stack_Size+FIQ_Stack_Size) AREA STACK,NOINIT,READWRITE,ALIGN=3 Stack_Mem SPACE Stack_Size Stack_Top EQU Stack_Mem+Stack_Size PRESERVE8 ;Area Definition and Entry Point AREA RESET,CODE,READONLY ARM ;Exception Vectors LDR PC,=Reset Undef LDR PC,=Undef SWInt LDR PC,=SWInt PAbt LDR PC,=PAbt DAbt LDR PC,=DAbt NOP LDR PC,[PC,#-0xF20] ;IRQ LDR PC,[PC,#-0xF20] ;FIQ ;Reset Handler Reset ;Setup Stack for each mode LDR R0,=Stack_Top ;Enter FIQ Mode and set its Stack Pointer MSR CPSR_c,#Mode_FIQ:OR:I_Bit:OR:F_Bit MOV SP,R0 SUB R0,R0,#FIQ_Stack_Size ;Enter IRQ Mode and set its Stack Pointer MSR CPSR_c,#Mode_IRQ:OR:I_Bit:OR:F_Bit MOV SP,R0 SUB R0,R0,#IRQ_Stack_Size ;Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c,#Mode_SVC MOV SP,R0 SUB R0,R0,#SVC_Stack_Size ;CLK IMPORT PrepareCLK BL PrepareCLK ;EBI IMPORT PrepareEBI BL PrepareEBI ;SPI IMPORT PrepareSPI BL PrepareSPI ;PIO IMPORT PreparePIO BL PreparePIO ;MMU IMPORT PrepareMMU BL PrepareMMU ;Return First-Level Translation Table Address in R0 ;Write First-Level Translation Table Address MCR p15,0,R0,c2,c0,0 ;Write Domain LDR R0,=0x00000003 MCR p15,0,R0,c3,c0,0 ;Enable ICache, DCache, MMU LDR R0,=0x4000507D MCR p15,0,R0,c1,c0,0 ;Enter the C code IMPORT __main BL __main ;User Initial Stack & Heap AREA |.text|,CODE,READONLY EXPORT __user_initial_stackheap __user_initial_stackheap EOR R0,R0 LDR R1,=(Stack_Mem+SVC_Stack_Size) EOR R2,R2 LDR R3,=Stack_Mem BX LR END Изменено 11 августа, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба 3 часа назад, __inline__ сказал: но был включен некий Bufferable (внятное назначение узнать не удалось, но он давал увеличение быстродействия при отрисовки на дисплей): В этом режиме при записи в память нескольких значений, последовательно, включается DDR Burst, поэтому идет ускорение, но только записи в память, чтение тут никакого ускорения не дает... 3 часа назад, __inline__ сказал: Я бы сказал, что не то что не рекомендуется, а её вообще нельзя кешировать Да я понимаю, но странное дело, в кортексе А8 (процы А10, А13) включение кэша экранной области не нарушало ничего, и добавляло скорости работы, может там организация кэша была сделана по-другому, или дисплейный модуль был подключен напрямую к ДДР, а не через кэш, как в А9 или А7 кортексах... Или может даже такая штука, т.к. включен режим кэша и буфера одновременно, при записи в экранную память происходило кэширование и сброс буфера в память одновременно, поэтому я мог и читать и писать в экранную область, используя кэш, но данные в дисплей отправлялись тоже корректно... Изменено 11 августа, 2019 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 11 августа, 2019 Опубликовано 11 августа, 2019 · Жалоба 3 minutes ago, mantech said: В этом режиме при записи в память нескольких значений, последовательно, включается DDR Burst, поэтому идет ускорение, но только записи в память, чтение тут никакого ускорения не дает... Спасибо, буду знать. На счёт чтения, не представляю себе пользы чтения видеопамяти дисплея. Всегда заводил промежуточный буфер и делал там все операции - по альфа-смешению и прочее - в системной памяти (которая кеширована на чтение и запись), затем сформированный буфер отсылал в дисплей (но он был не фрейм-буффером, а простым регистром данных с авто-инкрементом адреса внутри дисплейного контроллера. Читать память такого дисплея - дорогое удовольствие, к тому же всегда в формате пиксела 6:6:6, что неудобно когда используеься 5:6:5) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба 7 минут назад, __inline__ сказал: На счёт чтения, не представляю себе пользы чтения видеопамяти дисплея. Всегда заводил промежуточный буфер и делал там все операции - по альфа-смешению и прочее - в системной памяти (которая кеширована на чтение и запись), затем сформированный буфер отсылал в дисплей (но он был не фрейм-буффером, а простым регистром данных с авто-инкрементом адреса внутри дисплейного контроллера. Может вам повезло, и аппаратный блиттер с возможностью копирования блоков, был документирован, но в аллвиннерах тут все печально. И ДМА в этом случае помошник не очень, медленный он, кэшированные облсти копируются процом в 3 раза быстрее... Хотя есть и приятные моменты, все это дело, (ДМА, работа с памятью и копирование процом) на аллвиннерах работают куда лучше, чем в раскрученном IMX6... Изменено 11 августа, 2019 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба 42 minutes ago, mantech said: Может вам повезло, и аппаратный блиттер с возможностью копирования блоков, был документирован, но в аллвиннерах тут все печально. И ДМА в этом случае помошник не очень, медленный он, кэшированные облсти копируются процом в 3 раза быстрее... Хотя есть и приятные моменты, все это дело, (ДМА, работа с памятью и копирование процом) на аллвиннерах работают куда лучше, чем в раскрученном IMX6... Блиттера хардварного у меня не было. Всё делалось ручками (CPU). Ещё по наблюдением, нужно было немного корректировать времянки дисплея в бОльшую сторону с использованием кеширования и DMA (параметры циклов записи на шину) - возможно из-за более плотной передачи данных. Пока не скорректировал - были артефакты на дисплее, вплоть до срыва всего кадра и отключения дисплея (интерфейс общения с дисплеем простой - через 2 порта: команда, данные). На счёт медленности ДМА в оллвиннерах, может не всё так плохо? ДМА может хоть и медленее CPU перекидывает блок, но за счёт параллельности может давать выигрыш. К примеру: Программа идёт 9 мкс, отрисовка CPU 3 мкс - всего 12 мкс. С ДМА: программа - также 9 мкс, отрисовка ДМА: 9 мкс - в 3 раза медленее, но за счёт параллельности - суммарное время - 9 мкс вместо 12 мкс. Тот самый случай когда за счёт параллельности достигается небольшой выигрыш, хотя ДМА меделенный. На C6745 как-раз с этим сталкивался неоднократно - там встроенный сопроцессор PRUSS который намного слабже (частота вдвое ниже ядра, ограниченный набор команд, отсутствие кеша), чем сам DSP за счёт отрисовки параллельно давал нехилый суммарный выигрыш. Изменено 11 августа, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 11 августа, 2019 Опубликовано 11 августа, 2019 · Жалоба 53 минуты назад, __inline__ сказал: ДМА может хоть и медленее CPU перекидывает блок, но за счёт параллельности может давать выигрыш. Так-то да, только 90% случаев все-равно приходится ждать, пока завершится транзакция, чтоб потом начинать следующую. Небольшой выигрыш был только в анимации, когда можно поставить отрисовку на "автомат" и уйти обратно в программу, а ДМА пусть "рисует". Сейчас это и оставил на откуп ДМА, да сохранять\восстанавливать основной фон, при открытии форм ГУЯ и закрытии их всех полностью, ибо в этом случае приходится перерисовывать экран в 2 слоя, что утомительно для проца.. 58 минут назад, __inline__ сказал: Пока не скорректировал - были артефакты на дисплее, вплоть до срыва всего кадра и отключения дисплея (интерфейс общения с дисплеем простой - через 2 порта: команда, данные). У меня дисплей подключен к встроенному контроллеру, там все веселее с кэшем Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 11 августа, 2019 Опубликовано 11 августа, 2019 · Жалоба 2 часа назад, mantech сказал: Так-то да, только 90% случаев все-равно приходится ждать, пока завершится транзакция, чтоб потом начинать следующую. Плюс от использования DMA - не в увеличении скорости чего-то, а в уменьшении загрузки CPU. Когда освободившиеся такты CPU можно потратить на что-то более полезное, чем копирование байт из одного адреса в другой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 32 11 августа, 2019 Опубликовано 11 августа, 2019 · Жалоба 54 минуты назад, jcxz сказал: Плюс от использования DMA - не в увеличении скорости чего-то, а в уменьшении загрузки CPU. В том-то и дело, если такая нагрузка есть в данный момент. Если надо копировать N блоков, причем последовательно, и больше ничего в данный момент, кроме прерываний, на которые проц и так уйдет, когда будет вызов, то никакого выигрыша нет, скорей проигрыш, т.к. проц скопирует это быстрее. Возможно получить выигрыш при многозадачности или копировании больших блоков, причем из некэшируемой памяти в некэшируемую память, т.к. проц при этом доступ к памяти для проца очень затратный , особенно при чтении, т.к. запись можно буферировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 11 августа, 2019 Опубликовано 11 августа, 2019 (изменено) · Жалоба 9 hours ago, mantech said: В том-то и дело, если такая нагрузка есть в данный момент. Если надо копировать N блоков, причем последовательно, и больше ничего в данный момент, кроме прерываний, на которые проц и так уйдет, когда будет вызов, то никакого выигрыша нет, скорей проигрыш, т.к. проц скопирует это быстрее. Возможно получить выигрыш при многозадачности или копировании больших блоков, причем из некэшируемой памяти в некэшируемую память, т.к. проц при этом доступ к памяти для проца очень затратный , особенно при чтении, т.к. запись можно буферировать. Ради интереса поднял тесты на C6745. SDRAM 16 бит, 152 МГц. Кеширование включено. Передача буфера 128x128 коротких слов(2 байта на точку) разными порциями: байт, полу-слово, слово, двойное слово в дисплей (память закеширована, дисплей - нет): #define LCD_BASE 0x60000000 /* 32MB Async Data (CS2) */ #define LCD_I LCD_BASE #define LCD_D (LCD_BASE+0x00004000) /* A12 */ #define LCD_I8 (*(volatile unsigned char*)LCD_I) #define LCD_D8 (*(volatile unsigned char*)LCD_D) #define LCD_I16 (*(volatile unsigned short int*)LCD_I) #define LCD_D16 (*(volatile unsigned short int*)LCD_D) #define LCD_I32 (*(volatile unsigned int*)LCD_I) #define LCD_D32 (*(volatile unsigned int*)LCD_D) #define LCD_I64 (*(volatile unsigned long long*)LCD_I) #define LCD_D64 (*(volatile unsigned long long*)LCD_D) //64 bit transfer: 128x128 651 FPS n>>=3; register u64 *P=(u64*)&Picture[o]; while(n--)LCD_D64=*P++; //32 bit transfer: 128x128 615 FPS /* n>>=2; register u32 *P=(u32*)&Picture[o]; while(n--)LCD_D32=*P++; */ //16 bit transfer: 128x128 553 FPS /* n>>=1; register u16 *P=(u16*)&Picture[o]; while(n--)LCD_D16=*P++; */ //8 bit transfer: 128x128 461 FPS /* register u8 *P=(u8*)&Picture[o]; while(n--)LCD_D8=*P++; */ С ДМА получилось чуть-больше, чем с 64-битной передачей : //128x128 682 FPS void EDMA3_Run(void) { EDMA3_ESR=0x00000001; //Channel 0 set } Что важно, настройка DBS, меньше 32 байт даёт уже меньше производительность: L1P_Config(L1_SIZE_32K); //Enable L1P L1D L2 Cache L1D_Config(L1_SIZE_32K); L2_Config(L2_SIZE_256K); SDRAM_Cacheable(CACHEABLE_ON); //Enable SDRAM Cacheable CFGCHIP0=(2<<2)|2; //PLL MMRs unlock & TC1 64 byte & TC0 64 byte (DBS) В олвиннерах DBS регулируется? В случае DDR сохраняется однотактность доступа к памяти через DMA? Может в этом кроется причина медленной работы DMA с DDR ? В случае с C6745 SDRAM может работать в пакетном режиме - доступ вроде как однотактный там. Поэтому и DMA там довольно быстрый Изменено 11 августа, 2019 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 12 августа, 2019 Опубликовано 12 августа, 2019 · Жалоба 17 часов назад, mantech сказал: В том-то и дело, если такая нагрузка есть в данный момент. Если надо копировать N блоков, причем последовательно, и больше ничего в данный момент, кроме прерываний, на которые проц и так уйдет, когда будет вызов, то никакого выигрыша нет, скорей проигрыш, т.к. проц скопирует это быстрее. Ну во-первых: в случае с прерываниями как раз и будет выигрыш, так как если копирует CPU, то "уйдёт в ISR" - значит перестанет копировать, а если DMA - продолжит. Во-вторых: для описываемого случая (отрисовка в видеобуфере МК и отправка в видеопамять дисплея) частот как раз процессору всегда есть чем заняться. Так как часто бывает что закончив рисование очередного кадра, нужно как можно быстрее начать рисование следующего. Для всякой анимации - чем выше частота обновления - тем как правило лучше. И использование DMA в данном случае однозначно плюс. 17 часов назад, mantech сказал: Возможно получить выигрыш при многозадачности Да и в-3-их: на более-менее серьёзных МК работает как правило не одна задача одновременно. Так что CPU часто есть чем заняться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 12 августа, 2019 Опубликовано 12 августа, 2019 · Жалоба 1 minute ago, jcxz said: И использование DMA в данном случае однозначно плюс. Вот уж не однозначно. Оконный движок может рисовать в том же буфере, который отправляет на дисплей. Причем перерисовывает не все, а только то что требует перерисовки, т.е. только изменения в картинке. И тогда одновременная работа DMA и программной перерисовки будет вызывать на экране неприятные артефакты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться