|
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 { } }
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|