|
jpeg на at91sam9g20, скорость сжатия |
|
|
|
Aug 21 2010, 14:20
|
Частый гость
 
Группа: Участник
Сообщений: 111
Регистрация: 2-03-10
Пользователь №: 55 768

|
Делаю jpeg кодер для сжатия raw картинки с матрицы mt9d131. Картинка сжимается примерно за 3 секунды. Для такого контроллера это нормально? С помощью встроенного таймера пробовал измерять время на различных этапах сжатия. Около 400 милисекунд уходит на копирование буфера картинки. Как я понял очень много времени уходит на операции в памяти. Код for(i=0; i<614400; i++) { data[i] = Buffer[i]; } Картинка около 600 килобайт. Пробовал напрямую использовать буфер(Buffer), в который ISI интерфейс записывает картинку, но во время сжатия были искажения цветов, тоесть там что-то с обращением. Еще много времени уходит на квантование: CODE void fdct_and_quantization(SBYTE *data,float *fdtbl,SWORD *outdata) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; int z1, z2, z3, z4, z5, z11, z13; int *dataptr; int datafloat[64]; int temp; SBYTE ctr; BYTE i; for (i=0; i<64; i++) datafloat[i] = data[i];
dataptr=datafloat; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = dataptr[0] + dataptr[7]; tmp7 = dataptr[0] - dataptr[7]; tmp1 = dataptr[1] + dataptr[6]; tmp6 = dataptr[1] - dataptr[6]; tmp2 = dataptr[2] + dataptr[5]; tmp5 = dataptr[2] - dataptr[5]; tmp3 = dataptr[3] + dataptr[4]; tmp4 = dataptr[3] - dataptr[4];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */ dataptr[4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * (0.707106781); /* c4 */ dataptr[2] = tmp13 + z1; /* phase 5 */ dataptr[6] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */ z5 = (tmp10 - tmp12) * (0.382683433); /* c6 */ z2 = ( 0.541196100) * tmp10 + z5; /* c2-c6 */ z4 = ( 1.306562965) * tmp12 + z5; /* c2+c6 */ z3 = tmp11 * ( 0.707106781); /* c4 */
z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3;
dataptr[5] = z13 + z2; /* phase 6 */ dataptr[3] = z13 - z2; dataptr[1] = z11 + z4; dataptr[7] = z11 - z4;
dataptr += 8; /* advance pointer to next row */ }
dataptr = datafloat; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = dataptr[0] + dataptr[56]; tmp7 = dataptr[0] - dataptr[56]; tmp1 = dataptr[8] + dataptr[48]; tmp6 = dataptr[8] - dataptr[48]; tmp2 = dataptr[16] + dataptr[40]; tmp5 = dataptr[16] - dataptr[40]; tmp3 = dataptr[24] + dataptr[32]; tmp4 = dataptr[24] - dataptr[32];
/* Even part */
tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */ dataptr[32] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * ( 0.707106781); /* c4 */ dataptr[16] = tmp13 + z1; /* phase 5 */ dataptr[48] = tmp13 - z1;
/* Odd part */
tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7;
/* The rotator is modified from fig 4-8 to avoid extra negations. */ z5 = (tmp10 - tmp12) * ( 0.382683433); /* c6 */ z2 = ( 0.541196100) * tmp10 + z5; /* c2-c6 */ z4 = ( 1.306562965) * tmp12 + z5; /* c2+c6 */ z3 = tmp11 * ( 0.707106781); /* c4 */
z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3;
dataptr[40] = z13 + z2; /* phase 6 */ dataptr[24] = z13 - z2; dataptr[8] = z11 + z4; dataptr[56] = z11 - z4;
dataptr++; /* advance pointer to next column */ }
for (i = 0; i < 64; i++) { /* Apply the quantization and scaling factor */ outdata[i] = datafloat[i] * fdtbl[i]; } }
После замены у всех переменных типа float на int скорость сжатия возросла в 3 раза. В общем вопросы по порядку: 1. Как быстро скопировать переменную в памяти( или использовать буфер isi интерфейса без порчи картинки) 2. Ускорить функцию квантования(Хотел бы разместить часть переменных в sram( она же быстрее sdram?))
Сообщение отредактировал aaarrr - Aug 21 2010, 16:33
Причина редактирования: Оформление цитаты исходника
|
|
|
|
|
Aug 21 2010, 16:43
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(wmakc @ Aug 21 2010, 18:20)  Картинка сжимается примерно за 3 секунды. Для такого контроллера это нормально? Нет, это медленно. Цитата(wmakc @ Aug 21 2010, 18:20)  1. Как быстро скопировать переменную в памяти( или использовать буфер isi интерфейса без порчи картинки) Использовать не побайтное копирование, а, например, библиотечную функцию memcpy. Буферы выровнять по границе слова. Цитата(wmakc @ Aug 21 2010, 18:20)  2. Ускорить функцию квантования(Хотел бы разместить часть переменных в sram( она же быстрее sdram?)) Судя по скорости копирования, сейчас даже кэш не настроен. Да, в текущих условиях перенос переменных в SRAM принесет заметное ускорение. Но при нормальных настройках этого не потребуется.
|
|
|
|
|
Aug 21 2010, 20:27
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(AlexandrY @ Aug 22 2010, 00:14)  Ладно повторю яснее. И я попробую яснее. Если источник имеет одно выравнивание (скажем, младшие два бита адреса равны 1), а приемник другое (например, 3), то 32-битной пересылки пачками не получится в принципе. Максимум, что можно сделать (и делается в нормальных memcpy) - это 32-битное одинарное чтение, затем перепаковка и 32-битная запись. Иллюстрация: Код Word 0 1 2 3 4 0123 0123 0123 0123 0123 Source ABC DEFG HIJK LMNO Destination A BCDE FGHI JKLM NO
|
|
|
|
|
Aug 21 2010, 21:41
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(aaarrr @ Aug 21 2010, 23:27)  И я попробую яснее. Если источник имеет одно выравнивание (скажем, младшие два бита адреса равны 1), а приемник другое (например, 3), то 32-битной пересылки пачками не получится в принципе. Максимум, что можно сделать (и делается в нормальных memcpy) - это 32-битное одинарное чтение, затем перепаковка и 32-битная запись. Иллюстрация: Код Word 0 1 2 3 4 0123 0123 0123 0123 0123 Source ABC DEFG HIJK LMNO Destination A BCDE FGHI JKLM NO Согласен. Что-то замкнуло у меня. Надо будет проверить влияние этого на производительность.
|
|
|
|
|
Aug 22 2010, 05:45
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(wmakc @ Aug 22 2010, 09:16)  объясните как с помощью memcpy скопировать из char в int использую memcpy(dataint, datachar, 64); где и как поставить выравнивание? Если хотите ускорить выполнение, то выравнивать надо datachar. В Keil'е для этого существует __align(). Цитата(wmakc @ Aug 22 2010, 09:16)  Что нужно для настройки кэш? Создать Translation Table, включить MMU, включить кэш. ICache можно включить отдельно от MMU, но это полумера. Цитата(wmakc @ Aug 22 2010, 09:16)  Задавал вопрос о том как использовать sram. Если я просто переменные в функции объединю в блок #pragma arm section RW=sram объявление переменных #pragma arm section RW то после когда контроллер с помощью загрузчика копирует мою программу из флешки в sdram, как он поймет, что часть переменных нужно скопировать в sram? Чтобы понял, надо еще объяснить линкеру, куда класть объекты секции sram. Например: CODE FLASH 0x00000000 0x00020000 { FLASH 0x00000000 0x00020000 { start.o (startup, +First) } RAM 0x00200000 0x00008000 { * (sram) } SDRAM 0x00300000 0x00800000 { * (+RO, +RW, +ZI) } }
|
|
|
|
|
Aug 22 2010, 07:04
|
Частый гость
 
Группа: Участник
Сообщений: 111
Регистрация: 2-03-10
Пользователь №: 55 768

|
Хотелось бы по подробнее узнать как создать Translation Table,включить MMU. Если есть пример на Keil буду очень рад). Когда пытаюсь скопировать данные из char в int с помощью memcpy контроллер виснет. В связи с этим возник вопрос как использовать __align()? CODE Load_region 0x20000000 0x2000000 {
Fixed_region 0x20000000 { *(cstartup +First) .ANY (+RO +RW +ZI) } Relocate_region 0x200000 0x4000 { *.o (VECTOR, +First) } ARM_LIB_HEAP 0x21FFE000 EMPTY 0x1000 { } ARM_LIB_STACK 0x22000000 EMPTY -0x1000 { } }
Это мой scatter, где в нем описать объявление sram?
|
|
|
|
|
Aug 22 2010, 07:23
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(wmakc @ Aug 22 2010, 11:04)  Хотелось бы по подробнее узнать как создать Translation Table,включить MMU. Если есть пример на Keil буду очень рад). Пример можете посмотреть здесь. Только под 926 нужно внести мелкие коррективы. Цитата(wmakc @ Aug 22 2010, 11:04)  Когда пытаюсь скопировать данные из char в int с помощью memcpy контроллер виснет. В связи с этим возник вопрос как использовать __align()? Не должен он виснуть. А если виснет, то в этом никак не виновато выравнивание. Цитата(wmakc @ Aug 22 2010, 11:04)  Это мой scatter, где в нем описать объявление sram? Можно так: CODE Load_region 0x20000000 0x2000000 {
Fixed_region 0x20000000 { *(cstartup +First) .ANY (+RO +RW +ZI) } Relocate_region 0x200000 0x4000 { *.o (VECTOR, +First) }
SRAM1 0x300000 0x4000 { * (sram) } ARM_LIB_HEAP 0x21FFE000 EMPTY 0x1000 { } ARM_LIB_STACK 0x22000000 EMPTY -0x1000 { } }
|
|
|
|
|
Aug 22 2010, 09:01
|
Частый гость
 
Группа: Участник
Сообщений: 111
Регистрация: 2-03-10
Пользователь №: 55 768

|
CODE
void InitMMU(unsigned int *pTranslationTable) { int i; // Program the TTB _writeTTB((unsigned int) pTranslationTable); // Program the domain access register _writeDomain(0xC0000000);
// Reset table entries for (i = 0; i < 4096; ++i) pTranslationTable[i] = 0; // Program level 1 page table entry
pTranslationTable[0x3] = (0x3 << 20) | // Physical Address (1 << 10) | // Access in supervisor mode (15 << 5) | // Domain (1 << 4) | (1 << 3) | // Cachable 0x2; // Set as 1 Mbyte section
/* SDRAM entire mapping */ for(i=0;i<64;i++) pTranslationTable[0x200+i] = ((0x200+i) << 20) | // Physical Address (1 << 10) | // Access in supervisor mode (15 << 5) | // Domain (1 << 4) | (1 << 3) | // Cachable 0x2; // Set as 1 Mbyte section
pTranslationTable[0xFFF] = (0xFFF << 20) | // Physical Address (1 << 10) | // Access in supervisor mode (15 << 5) | // Domain (1 << 4) | 0x2; // Set as 1 Mbyte section
// Enable the MMU CP15_EnableMMU(); }
int main(void) { CP15_Enable_I_Cache(); InitMMU((unsigned int *) 0x310000);
Попробовал запустить MMU. Все операции с памятью теперь не работают. В чем ошибка?
|
|
|
|
|
Aug 22 2010, 11:48
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(wmakc @ Aug 22 2010, 14:26)  Как использовать memcpy для копирования из массива char в int? а то когда копировал, получалось что char просто записывается в каждый байт int. тоесть если в char {0xAB, 0xFA, 0xFF, 0x01} то один int получится 0xABFAFF01, а мне нужно чтобы было 0x000000AB, 0x000000FA и т.д. Пробовал объявлять char c __align. Результата не дало От это вы зря спросили, щаз ваш пост снесут в раздел для самых начинающих новичков. Даже знаете, боюсь что мой ответ пролетит мимо, поскольку покуда я пишу ответ вашего поста может тут уже не быть. Скажу коротко: memcpy для такого переноса данных не подойдет.
|
|
|
|
|
Aug 22 2010, 16:21
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(wmakc @ Aug 22 2010, 14:34)  Пробовал в sdram, результата не дало Как пробовали и что именно получили? Цитата(wmakc @ Aug 22 2010, 15:26)  Как использовать memcpy для копирования из массива char в int? а то когда копировал, получалось что char просто записывается в каждый байт int. тоесть если в char {0xAB, 0xFA, 0xFF, 0x01} то один int получится 0xABFAFF01, а мне нужно чтобы было 0x000000AB, 0x000000FA и т.д. Так это уже не копирование совсем, а перепаковка данных. Ее придется сделать руками.
|
|
|
|
|
Aug 24 2010, 10:55
|
Частый гость
 
Группа: Участник
Сообщений: 111
Регистрация: 2-03-10
Пользователь №: 55 768

|
Цитата(etoja @ Aug 24 2010, 10:54)  Камера mt9d131 может выдавать картинку сразу в формате JPEG. Так зачем мучаться? Будет использоваться еще одна матрица и у нее нет сжатия jpeg, поэтому и нужно было реализовать кодек в контроллере. С возможностью матрицы выводить jpeg тоже нужно будет разобраться Цитата(andrewlekar @ Aug 24 2010, 08:40)  Да и 3 секунды для такой картинки это много. У меня оцифровка, ресайз и сжатие занимала без кэширования порядка секунды. С кэшированием насколько я помню около 0,3 секунды. Ну и простор для оптимизации ещё очень большой. Процессор AT91SAM9260. С кешированием и MMU я вроде как разобрался, теперь сжимает за пол секунды. А оптимизировать нужно функцию дисретного косинусного преобразования и квантования. Пока не знаю как
|
|
|
|
|
Aug 24 2010, 15:01
|
Частый гость
 
Группа: Участник
Сообщений: 111
Регистрация: 2-03-10
Пользователь №: 55 768

|
Если есть еще какие - то способы по улучшению быстродействия, или возможности ускорить jpeg, напишите, попробую реализовать.
Сейчас пытаюсь разобраться с матрицей mt9v136. В даташите написано, что на нее нужно подавать частоту 27 МГц, а эта частота считается из PLLA, как бы мне PLLA настроить так чтобы получить кратную 27? Понимаю, что возможно это просто, но до этого такой необходимости не было, поэтому еще не разобрался
Сообщение отредактировал wmakc - Aug 24 2010, 15:01
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|